Open In App

Minimize deletions such that sum of position of characters is at most K

Improve
Improve
Like Article
Like
Save
Share
Report

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>


Output

eefee

Time Complexity: O(N * log(N)) where N is the length of the string
Auxiliary Space: O(N)



Last Updated : 05 Sep, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads