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++
#include <bits/stdc++.h>
using namespace std;
string findMaxSubstring(string S, int K)
{
int n = S.size();
int totalCost = 0;
for ( int i = 0; i < n; i++) {
totalCost += (S[i] - 'a' + 1);
}
string temp(S);
sort(temp.rbegin(), temp.rend());
map< char , int > del;
for ( int i = 0; i < temp.length(); i++) {
if (totalCost > K) {
del[temp[i]]++;
totalCost -= temp[i] - 'a' + 1;
}
}
string ans;
for ( int i = 0; i < n; i++) {
if (del[S[i]] > 0) {
del[S[i]]--;
}
else {
ans += S[i];
}
}
return ans;
}
int main()
{
string S = "geeksforgeeks" ;
int K = 27;
string ans = findMaxSubstring(S, K);
cout << ans;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static String findMaxSubstring(String S, int K)
{
int n = S.length();
int totalCost = 0 ;
for ( int i = 0 ; i < n; i++) {
totalCost += (S[i] - 'a' + 1 );
}
String temp = new String(S);
Arrays.sort(temp);
Map <Character, Integer>del= new HashMap<Character, Integer>();
for ( int i = 0 ; i < temp.length(); i++) {
if (totalCost > K) {
del[temp[i]]++;
totalCost -= temp[i] - 'a' + 1 ;
}
}
String ans;
for ( int i = 0 ; i < n; i++) {
if (del[S[i]] > 0 ) {
del[S[i]]--;
}
else {
ans += S[i];
}
}
return ans;
}
public static void main (String[] args) {
String S = "geeksforgeeks" ;
int K = 27 ;
String ans = findMaxSubstring(S, K);
System.out.println(ans);
}
}
|
Python3
def findMaxSubstring(S, K) :
n = len (S);
totalCost = 0 ;
for i in range (n) :
totalCost + = ( ord (S[i]) - ord ( 'a' ) + 1 );
temp = list (S);
temp.sort(reverse = True );
delete = dict .fromkeys(temp, 0 );
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 = "";
for i in range (n) :
if (delete[S[i]] > 0 ) :
delete[S[i]] - = 1 ;
else :
ans + = S[i];
return ans;
if __name__ = = "__main__" :
S = "geeksforgeeks" ;
K = 27 ;
ans = findMaxSubstring(S, K);
print (ans);
|
C#
using System;
using System.Collections.Generic;
public class GFG{
static public string findMaxSubstring( string S, int K)
{
int n = S.Length;
int totalCost = 0;
for ( int i = 0; i < n; i++) {
totalCost += (S[i] - 'a' + 1);
}
string temp = String.Copy(S);
char []arr = temp.ToCharArray();
Array.Sort(arr);
Array.Reverse(arr);
Dictionary< char , int > del = new Dictionary< char , int >();
for ( char i= 'a' ;i<= 'z' ;i++){
del[i]=0;
}
string str = new string (arr);
for ( int i = 0; i < str.Length; i++) {
if (totalCost > K) {
del[str[i]]++;
totalCost -= arr[i] - 'a' + 1;
}
}
string ans= "" ;
for ( int i = 0; i < n; i++) {
if (del[S[i]] > 0) {
del[S[i]]--;
}
else {
ans += S[i];
}
}
return ans;
}
static public void Main (){
string S = "geeksforgeeks" ;
int K = 27;
string ans = findMaxSubstring(S, K);
Console.WriteLine(ans);
}
}
|
Javascript
<script>
function findMaxSubstring(S,K)
{
let n = S.length;
let totalCost = 0;
for (let i = 0; i < n; i++) {
let a = 'a' ;
totalCost += (S[i].charCodeAt(0) - a.charCodeAt(0) + 1);
}
let temp = S.slice();
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( "" );
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= "" ;
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];
}
}
return ans;
}
let S = "geeksforgeeks" ;
let K = 27;
let ans = findMaxSubstring(S, K);
console.log(ans);
</script>
|
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
Share your thoughts in the comments
Please Login to comment...