Minimize deletions such that sum of position of characters is at most K
Given a string S consisting of lower case letters and an integer K, the task is to remove minimum number of letters from the string, such that the sum of alphabetic ordering of the letters present in the string is at most K.
Examples :
Input: S = “abca”, K = 2
Output: “aa”
Explanation: Initial sum for the given string is 1 + 2 + 3 + 1 = 7
(since positions of a, b, and c are 1, 2, and 3 respectively).
If we remove b and c from the string “abca”, it becomes “aa”,
having cost 2 which is less than or equal to the given K.Input: S = “geeksforgeeks”, K= 27
Output: “eefee”
Approach: The problem can be easily solved by a greedy approach.
The main observation is that first, we must remove the characters having maximum cost before removing the characters having lesser cost.
- First create a variable (say totalCost), to store the total cost of the initial string S.
- Then create a copy of string S (say temp) and sort it in reverse order of characters.
- Traverse through temp and keep storing the characters in a map (say del), till totalCost is greater than K.
- These characters stored in the map are basically the characters to be deleted.
- Finally, traverse through the string S, delete the characters stored in the map del, and return the final string.
Below is the implementation of the above approach:
C++
// C++ code to implement the above approach #include <bits/stdc++.h> using namespace std; // Function to remove minimum number of // letters from the string, such that the // cost of the string becomes // less than or equal to K string findMaxSubstring(string S, int K) { int n = S.size(); // totalCost variable stores the cost // of the given string int totalCost = 0; for (int i = 0; i < n; i++) { totalCost += (S[i] - 'a' + 1); } // temp string is the copy of // given string S string temp(S); // Sort temp string in reverse // order of characters sort(temp.rbegin(), temp.rend()); map<char, int> del; // Traverse through the temp and store // the frequency of characters to be // deleted in the map "del" for (int i = 0; i < temp.length(); i++) { if (totalCost > K) { del[temp[i]]++; totalCost -= temp[i] - 'a' + 1; } } string ans; // Now traverse through the string S // and keep adding the characters into // the ans string if its frequency // in del is zero for (int i = 0; i < n; i++) { if (del[S[i]] > 0) { del[S[i]]--; } else { ans += S[i]; } } // Returning answer string return ans; } // Driver code int main() { string S = "geeksforgeeks"; int K = 27; // Function call string ans = findMaxSubstring(S, K); cout << ans; return 0; }
Java
/*package whatever //do not write package name here */ import java.io.*; import java.util.*; // Java code to implement the above approach class GFG { // Function to remove minimum number of // letters from the string, such that the // cost of the string becomes // less than or equal to K public static String findMaxSubstring(String S, int K) { int n = S.length(); // totalCost variable stores the cost // of the given string int totalCost = 0; for (int i = 0; i < n; i++) { totalCost += (S[i] - 'a' + 1); } // temp string is the copy of // given string S String temp = new String(S); // Sort temp string in reverse // order of characters Arrays.sort(temp); Map <Character, Integer>del= new HashMap<Character, Integer>(); // Traverse through the temp and store // the frequency of characters to be // deleted in the map "del" for (int i = 0; i < temp.length(); i++) { if (totalCost > K) { del[temp[i]]++; totalCost -= temp[i] - 'a' + 1; } } String ans; // Now traverse through the string S // and keep adding the characters into // the ans string if its frequency // in del is zero for (int i = 0; i < n; i++) { if (del[S[i]] > 0) { del[S[i]]--; } else { ans += S[i]; } } // Returning answer string return ans; } // Driver code public static void main (String[] args) { String S = "geeksforgeeks"; int K = 27; // Function call String ans = findMaxSubstring(S, K); System.out.println(ans); } } // This code is contributed by satwik4409.
Python3
# Python3 code to implement the above approach # Function to remove minimum number of # letters from the string, such that the # cost of the string becomes # less than or equal to K def findMaxSubstring(S, K) : n = len(S); # totalCost variable stores the cost # of the given string totalCost = 0; for i in range(n) : totalCost += (ord(S[i]) - ord('a') + 1); # temp string is the copy of # given string S temp = list(S); # Sort temp string in reverse # order of characters temp.sort(reverse = True); delete = dict.fromkeys(temp,0); # Traverse through the temp and store # the frequency of characters to be # deleted in the map "del" for i in range(len(temp)) : if (totalCost > K) : if temp[i] in delete : delete[temp[i]] += 1 else : delete[temp[i]] = 1 totalCost -= ord(temp[i]) - ord('a') + 1; ans = ""; # Now traverse through the string S # and keep adding the characters into # the ans string if its frequency # in del is zero for i in range(n) : if (delete[S[i]] > 0) : delete[S[i]] -= 1; else : ans += S[i]; # Returning answer string return ans; # Driver code if __name__ == "__main__" : S = "geeksforgeeks"; K = 27; # Function call ans = findMaxSubstring(S, K); print(ans); # This code is contributed by AnkThon
C#
using System; using System.Collections.Generic; public class GFG{ // Function to remove minimum number of // letters from the string, such that the // cost of the string becomes // less than or equal to K static public string findMaxSubstring(string S, int K) { int n = S.Length; // totalCost variable stores the cost // of the given string int totalCost = 0; for (int i = 0; i < n; i++) { totalCost += (S[i] - 'a' + 1); } // temp string is the copy of // given string S string temp = String.Copy(S); // Sort temp string in reverse // order of characters and store it in a char array named arr char []arr = temp.ToCharArray(); Array.Sort(arr); Array.Reverse(arr); //map<char, int> del; Dictionary<char,int> del = new Dictionary<char,int>(); for(char i='a';i<='z';i++){ del[i]=0; } string str = new string(arr); // Traverse through the temp and store // the frequency of characters to be // deleted in the map "del" for (int i = 0; i < str.Length; i++) { if (totalCost > K) { del[str[i]]++; totalCost -= arr[i] - 'a' + 1; } } string ans=""; // Now traverse through the string S // and keep adding the characters into // the ans string if its frequency // in del is zero for (int i = 0; i < n; i++) { if (del[S[i]] > 0) { del[S[i]]--; } else { ans += S[i]; } } // Returning answer string return ans; } static public void Main (){ string S = "geeksforgeeks"; int K = 27; // Function call string ans = findMaxSubstring(S, K); Console.WriteLine(ans); } } // This code is contributed by akashish__
Javascript
<script> // Function to remove minimum number of // letters from the string, such that the // cost of the string becomes // less than or equal to K function findMaxSubstring(S,K) { let n = S.length; // totalCost variable stores the cost // of the given string let totalCost = 0; for (let i = 0; i < n; i++) { let a = 'a'; totalCost += (S[i].charCodeAt(0) - a.charCodeAt(0) + 1); } // temp string is the copy of // given string S // let temp(S); let temp = S.slice(); // Sort temp string in reverse // order of characters let arr = [...temp]; arr.sort(); arr.reverse(); let del = new Map(); for(let i=97;i<=122;i++) { let char = String.fromCharCode(i) del.set(char,0); } let str = arr.join(""); // Traverse through the temp and store // the frequency of characters to be // deleted in the map "del" for (let i = 0; i < str.length; i++) { if (totalCost > K) { let value = del.get(str[i])+1; del.set(str[i],value); totalCost -= arr[i].charCodeAt(0) - 'a'.charCodeAt(0) + 1; } } let ans=""; // Now traverse through the string S // and keep adding the characters into // the ans string if its frequency // in del is zero for (let i = 0; i < n; i++) { if (del.get(S[i]) > 0) { let value = del.get(S[i]); del.set(S[i],value-1); } else { ans += S[i]; } } // Returning answer string return ans; } let S = "geeksforgeeks"; let K = 27; // Function call let ans = findMaxSubstring(S, K); console.log(ans); // This code is contributed by akashish__ </script>
eefee
Time Complexity: O(N * log(N)) where N is the length of the string
Auxiliary Space: O(N)
Please Login to comment...