Given a string s and an integer k, the task is to remove k characters from the string such that the sum of ASCII (American Standard Code for Information Interchange) values of the remaining characters is minimized.
Examples:
Input: s = “ABbc”, k = 2
Output: 131
Explanation: We need to remove exactly 2 characters from the string “ABbc” to minimize the ASCII sum of the remaining characters. By removing ‘b’ and ‘c’, we obtain the minimum sum of 131, which corresponds to the ASCII sum of the remaining characters (‘A’ and ‘B’).Input: s = “abaacd”, k = 3
Output: 291
Explanation: We need to remove exactly 3 characters from the string “abaacd” to minimize the ASCII sum of the remaining characters. By removing ‘b’, ‘c’, and ‘d’, we obtain the minimum sum of 297, which corresponds to the ASCII sum of the remaining characters (‘a’, ‘a’, and ‘a’).
Approach: To solve the problem follow the below idea:
To solve this problem, we can use a Greedy approach. The idea is to sort the characters of the given string in ascending order of their ASCII values, and then remove k characters from the end of the sorted string. This approach ensures that we are removing characters with the highest ASCII values, which will result in the minimum sum of the remaining characters.
Here are the steps of the approach:
- Create an array to store the frequency of each character in the string s.
- Sort the characters of the string s in ascending order of their ASCII values.
- Traverse the sorted string s, and for each character, decrement its frequency in the frequency array.
-
While traversing the sorted string s, keep track of the number of characters removed so far.
- If the current character has a frequency greater than k, then remove k characters from the end of the sorted string s, and break the loop.
- Otherwise, remove all the characters of the current character from the end of the sorted string s, and subtract its ASCII value multiplied by its frequency from the sum of the remaining characters.
- If k characters have been removed, then break the loop.
- If the loop completes without breaking, then remove the remaining k characters from the end of the sorted string s, and subtract their ASCII values from the sum of the remaining characters.
- Return the sum of the remaining characters.
Below is the implementation of the above approach:
// C++ code for the above approach: #include <bits/stdc++.h> using namespace std;
int minAsciiSum(string s, int k)
{ int freq[26] = { 0 };
for ( int i = 0; i < s.length(); i++) {
freq[s[i] - 'a' ]++;
}
sort(s.begin(), s.end());
int sum = 0, removed = 0;
for ( int i = 0; i < s.length(); i++) {
int ch = s[i] - 'a' ;
if (freq[ch] > k - removed) {
sum += (k - removed) * (s[i]);
removed = k;
break ;
}
else {
sum += freq[ch] * (s[i]);
removed += freq[ch];
freq[ch] = 0;
}
if (removed == k) {
break ;
}
}
if (removed < k) {
sum += (k - removed) * (s[s.length() - 1]);
}
return sum;
} // Drivers code int main()
{ string s = "abaacd" ;
int k = 3;
// Function Call
cout << minAsciiSum(s, k) << endl;
return 0;
} |
// Java code for the above approach: import java.util.*;
class GFG {
static int minAsciiSum(String s, int k)
{
int freq[] = new int [ 26 ];
for ( int i = 0 ; i < s.length(); i++) {
freq[s.charAt(i) - 'a' ]++;
}
char [] ch = s.toCharArray();
Arrays.sort(ch);
s = new String(ch);
int sum = 0 , removed = 0 ;
for ( int i = 0 ; i < s.length(); i++) {
int ch1 = s.charAt(i) - 'a' ;
if (freq[ch1] > k - removed) {
sum += (k - removed) * (s.charAt(i));
removed = k;
break ;
}
else {
sum += freq[ch1] * (s.charAt(i));
removed += freq[ch1];
freq[ch1] = 0 ;
}
if (removed == k) {
break ;
}
}
if (removed < k) {
sum += (k - removed)
* (s.charAt(s.length() - 1 ));
}
return sum;
}
// Driver code
public static void main(String[] args)
{
String s = "abaacd" ;
int k = 3 ;
// Function Call
System.out.println(minAsciiSum(s, k));
}
} // This code is contributed by Tapesh(tapeshdua420) |
# python code for the above approach: def minAsciiSum(s, k):
freq = [ 0 ] * 26
for ch in s:
freq[ ord (ch) - ord ( 'a' )] + = 1
s = sorted (s)
sum = 0
removed = 0
for ch in s:
idx = ord (ch) - ord ( 'a' )
if freq[idx] > k - removed:
sum + = (k - removed) * ord (ch)
removed = k
break
else :
sum + = freq[idx] * ord (ch)
removed + = freq[idx]
freq[idx] = 0
if removed = = k:
break
if removed < k:
sum + = (k - removed) * ord (s[ - 1 ])
return sum
# Driver Code if __name__ = = '__main__' :
s = "abaacd"
k = 3
# Function Call
print (minAsciiSum(s, k))
|
// C# code for the above approach: using System;
using System.Linq;
class GFG
{ static int MinAsciiSum( string s, int k)
{
int [] freq = new int [26];
// Calculate the frequency of each character in the
// input string 's'
foreach ( char c in s)
{
freq++;
}
// Sort the string in ascending order
char [] sortedS = s.OrderBy(c => c).ToArray();
int sum = 0, removed = 0;
// Loop through the sorted string 'sortedS'
for ( int i = 0; i < sortedS.Length; i++)
{
char ch = sortedS[i];
int charIndex = ch - 'a' ;
// Check if the frequency of the current character
// is greater than 'k - removed'
if (freq[charIndex] > k - removed)
{
// Add the sum of ASCII values of (k - removed)
// instances of the character 'ch' to 'sum'
sum += (k - removed) * ch;
removed = k;
break ;
}
else
{
// Add the sum of ASCII values of all instances of
// the character 'ch' to 'sum'
sum += freq[charIndex] * ch;
// Update 'removed' by adding the frequency of
// the current character to it
removed += freq[charIndex];
// Set the frequency of the character to zero to
// mark it as "removed"
freq[charIndex] = 0;
}
// Check if we have removed 'k' characters,
// break out of the loop
if (removed == k)
{
break ;
}
}
// If 'removed' is still less than 'k', add the sum
// of ASCII values of (k - removed) instances of the last
// character in the sorted string
if (removed < k)
{
char lastChar = sortedS[sortedS.Length - 1];
sum += (k - removed) * lastChar;
}
return sum;
}
//Driver code static void Main()
{
string s = "abaacd" ;
int k = 3;
// Function Call
Console.WriteLine(MinAsciiSum(s, k));
}
} |
// JavaScript code for the above approach: function minAsciiSum(s, k) {
let freq = new Array(26).fill(0);
for (let ch of s) {
freq[ch.charCodeAt(0) - 'a' .charCodeAt(0)] += 1;
}
s = s.split( '' ).sort().join( '' );
let sum = 0;
let removed = 0;
for (let ch of s) {
let idx = ch.charCodeAt(0) - 'a' .charCodeAt(0);
if (freq[idx] > k - removed) {
sum += (k - removed) * ch.charCodeAt(0);
removed = k;
break ;
} else {
sum += freq[idx] * ch.charCodeAt(0);
removed += freq[idx];
freq[idx] = 0;
}
if (removed === k) {
break ;
}
}
if (removed < k) {
sum += (k - removed) * s.charCodeAt(s.length - 1);
}
return sum;
} // Driver Code let s = "abaacd" ;
let k = 3; // Function Call console.log(minAsciiSum(s, k)); // This code is contributed by Tapesh(tapeshdua420) |
291
Time Complexity: O(n*logn), where n is the length of the string.
Auxiliary Space: O(1), because we are using a fixed-size array of size 26 to store the frequency of each character in the string.