Open In App

Generate longest String with character sum at most K by deleting letters

Last Updated : 21 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string str and an integer K, the task is to find the longest string that can be made by deleting letters from the given string such that the sum of the characters of the remaining string is at most K.

Note: The value of the string is calculated as the sum of the value of characters (a value is 1, b value is 2…., z value is 26).

Examples:

Input:  str = “geeksforgeeks”, K = 15
Output: eee
Explanation: After deleting the characters string gets reduced to eee whose value is 5 + 5 +  5 = 15 which is less than or equal to K i.e. 15

Input: str = “abca”, K = 6
Output: aba
Explanation: Initial value of str 1 + 2 + 3 + 1 = 7, after deleting the letter c, the string gets reduced to aba whose value is 1+2+1 = 4 which is less than K i.e. 6.

Approach: The problem can be solved using Greedy approach based on the following idea:

We must delete letters with the highest value first. So, we sort the string str in decreasing order and will be deleting letters from the starting of string str as long as the initial value of string str is greater than the given value K.

Follow the steps mentioned below to implement the idea:

  • Calculate the initial value of the given string.
  • Sort the string str in decreasing order
  • Start removing the value of the current letter from the initial value as long as the initial value is greater than K.
    • Store the removed characters in the map
  • Iterate through the given string once again and 
    • If the current letter does not exist in the map take it into the resultant string
    • Else decrease the frequency of the letter
  • Return the resultant string

Below is the implementation of the above approach:

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function for finding out string with value
// less than or equal to K
string minimise_str(string str, int K)
{
    int initial_value = 0;
 
    // Calculate initial value of string
    for (int i = 0; i < str.length(); i++) {
        initial_value += (str[i] - 'a') + 1;
    }
 
    string temp = str;
 
    // Sort the string in decreasing order
    sort(str.begin(), str.end());
    reverse(str.begin(), str.end());
 
    // Store the deleted letters
    unordered_map<char, int> mpp;
    int i = 0;
 
    // Remove letters as long as the initial
    // value is greater than K
    while (initial_value > K) {
        initial_value -= (str[i] - 'a') + 1;
        mpp[str[i]]++;
        i++;
    }
 
    // Store resultant string
    string ans = "";
    for (int i = 0; i < temp.size(); i++) {
 
        // If letter do exist in map, decrease
        // frequency
        if (mpp[temp[i]] > 0) {
            mpp[temp[i]]--;
        }
        // Else store the letter in resultant
        // string
        else {
            ans += temp[i];
        }
    }
 
    // Return resultant string
    return ans;
}
 
// Driver code
int main()
{
    string str = "geeksforgeeks";
    int K = 15;
 
    // Function call
    cout << minimise_str(str, K);
 
    return 0;
}


Java




// Java code to implement the approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function for finding out string with value less than
    // or equal to K
    static String minimiseStr(String str, int K)
    {
        int initialValue = 0;
 
        // Calculate initial value of string
        for (int i = 0; i < str.length(); i++) {
            initialValue += (str.charAt(i) - 'a') + 1;
        }
 
        String temp = str;
 
        // Sort the string in decreasing order
        char[] chars = str.toCharArray();
        Arrays.sort(chars);
        str = new StringBuilder(new String(chars))
                  .reverse()
                  .toString();
 
        // Store the deleted letters
        Map<Character, Integer> mpp = new HashMap<>();
        int i = 0;
 
        // Remove letters as long as the initial value is
        // greater than K
        while (initialValue > K) {
            initialValue -= (str.charAt(i) - 'a') + 1;
            mpp.put(str.charAt(i),
                    mpp.getOrDefault(str.charAt(i), 0) + 1);
            i++;
        }
 
        // Store resultant string
        StringBuilder ans = new StringBuilder();
        for (int j = 0; j < temp.length(); j++) {
 
            // If letter do exist in map, decrease frequency
            if (mpp.containsKey(temp.charAt(j))
                && mpp.get(temp.charAt(j)) > 0) {
                int freq = mpp.get(temp.charAt(j));
                mpp.put(temp.charAt(j), freq - 1);
            }
            // Else store the letter in resultant string
            else {
                ans.append(temp.charAt(j));
            }
        }
 
        // Return resultant string
        return ans.toString();
    }
 
    public static void main(String[] args)
    {
        String str = "geeksforgeeks";
        int K = 15;
 
        // Function call
        System.out.println(minimiseStr(str, K));
    }
}
 
// This code is contributed by karthik.


Python3




# python code imple.
 
import collections
 
def minimise_str(str, K):
    initial_value = 0
 
    # Calculate initial value of string
    for i in range(len(str)):
        initial_value += (ord(str[i]) - ord('a') + 1)
 
    temp = str
 
    # Sort the string in decreasing order
    str = ''.join(sorted(str, reverse=True))
 
    # Store the deleted letters
    mpp = collections.defaultdict(int)
    i = 0
 
    # Remove letters as long as the initial
    # value is greater than K
    while initial_value > K:
        initial_value -= (ord(str[i]) - ord('a') + 1)
        mpp[str[i]] += 1
        i += 1
 
    # Store resultant string
    ans = ""
    for i in range(len(temp)):
 
        # If letter do exist in map, decrease
        # frequency
        if mpp[temp[i]] > 0:
            mpp[temp[i]] -= 1
        # Else store the letter in resultant
        # string
        else:
            ans += temp[i]
 
    # Return resultant string
    return ans
 
# Driver code
str = "geeksforgeeks"
K = 15
 
# Function call
print(minimise_str(str, K))
 
#code by ksam24000


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class GFG
{
// Function for finding out string with value
// less than or equal to K
static string MinimiseString(string str, int K)
{
int initial_value = 0;
 
 
    // Calculate initial value of string
    foreach (char c in str)
    {
        initial_value += (c - 'a') + 1;
    }
 
    string temp = str;
 
    // Sort the string in decreasing order
    char[] arr = str.ToCharArray();
    Array.Sort(arr);
    Array.Reverse(arr);
    str = new string(arr);
 
    // Store the deleted letters
    Dictionary<char, int> mpp = new Dictionary<char, int>();
    int i = 0;
 
    // Remove letters as long as the initial
    // value is greater than K
    while (initial_value > K)
    {
        initial_value -= (str[i] - 'a') + 1;
        if (mpp.ContainsKey(str[i]))
        {
            mpp[str[i]]++;
        }
        else
        {
            mpp[str[i]] = 1;
        }
        i++;
    }
 
    // Store resultant string
    string ans = "";
    foreach (char c in temp)
    {
        // If letter do exist in map, decrease
        // frequency
        if (mpp.ContainsKey(c) && mpp > 0)
        {
            mpp--;
        }
        // Else store the letter in resultant
        // string
        else
        {
            ans += c;
        }
    }
 
    // Return resultant string
    return ans;
}
 
// Driver code
static void Main(string[] args)
{
    string str = "geeksforgeeks";
    int K = 15;
 
    // Function call
    Console.WriteLine(MinimiseString(str, K));
}
}


Javascript




function minimiseStr(str, K) {
  let initialValue = 0;
 
  // Calculate initial value of string
  for (let i = 0; i < str.length; i++) {
    initialValue += (str.charCodeAt(i) - 'a'.charCodeAt(0)) + 1;
  }
 
  let temp = str;
 
  // Sort the string in decreasing order
  str = str.split('').sort().reverse().join('');
 
  // Store the deleted letters
  let mpp = {};
  let i = 0;
 
  // Remove letters as long as the initial
  // value is greater than K
  while (initialValue > K) {
    initialValue -= (str.charCodeAt(i) - 'a'.charCodeAt(0)) + 1;
    if (mpp[str[i]]) {
      mpp[str[i]]++;
    } else {
      mpp[str[i]] = 1;
    }
    i++;
  }
 
  // Store resultant string
  let ans = '';
  for (let i = 0; i < temp.length; i++) {
    // If letter do exist in map, decrease
    // frequency
    if (mpp[temp[i]] > 0) {
      mpp[temp[i]]--;
    }
    // Else store the letter in resultant
    // string
    else {
      ans += temp[i];
    }
  }
 
  // Return resultant string
  return ans;
}
 
// Driver code
let str = 'geeksforgeeks';
let K = 15;
//Function call
document.write(minimiseStr(str, K));


Output

eee

Time Complexity: O(N * logN)
Auxiliary Space: O(N)

Related Articles:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads