Remove k characters in a String such that ASCII sum is minimum
Last Updated :
08 Feb, 2024
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++
#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;
}
int main()
{
string s = "abaacd" ;
int k = 3;
cout << minAsciiSum(s, k) << endl;
return 0;
}
|
Java
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;
}
public static void main(String[] args)
{
String s = "abaacd" ;
int k = 3 ;
System.out.println(minAsciiSum(s, k));
}
}
|
Python3
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
if __name__ = = '__main__' :
s = "abaacd"
k = 3
print (minAsciiSum(s, k))
|
C#
using System;
using System.Linq;
class GFG
{
static int MinAsciiSum( string s, int k)
{
int [] freq = new int [26];
foreach ( char c in s)
{
freq++;
}
char [] sortedS = s.OrderBy(c => c).ToArray();
int sum = 0, removed = 0;
for ( int i = 0; i < sortedS.Length; i++)
{
char ch = sortedS[i];
int charIndex = ch - 'a' ;
if (freq[charIndex] > k - removed)
{
sum += (k - removed) * ch;
removed = k;
break ;
}
else
{
sum += freq[charIndex] * ch;
removed += freq[charIndex];
freq[charIndex] = 0;
}
if (removed == k)
{
break ;
}
}
if (removed < k)
{
char lastChar = sortedS[sortedS.Length - 1];
sum += (k - removed) * lastChar;
}
return sum;
}
static void Main()
{
string s = "abaacd" ;
int k = 3;
Console.WriteLine(MinAsciiSum(s, k));
}
}
|
Javascript
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;
}
let s = "abaacd" ;
let k = 3;
console.log(minAsciiSum(s, k));
|
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.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...