Minimum deletions required to make frequency of each letter unique

Given a string S consisting of lowercase characters, you have to delete the minimum number of characters from S so that every letter in S appears a unique number of times.

Examples:

Input: str = “aaaabbbb”
Output: 1
Both ‘a’ and ‘b’ occur 4 times if the first character is deleted then ‘a’ occurs 3 times and ‘b’ occurs 4 times.



Input: str = “geeksforgeeks”
Output: 6

Approach:

  • We can count the frequencies of all 26 possible lower case characters.
  • Then construct a map that tells how many letters have a given frequency.
  • Iterate the map from higher frequencies to lower.
    1. If more than 1 letter has a given frequency we delete 1 occurrence of all but 1 letter with that frequency.
    2. Deleting 1 occurrence of those letters increases the number of the letter that has the frequency one less.
  • If the occurrence of a letter is 0 then it is not present in the string.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the
// approach
#include <bits/stdc++.h>
using namespace std;
  
// Returns the mininum number
// of characters to be deleted
// so that all remaining characters
// occur unique number of times.
int minimumDeletions(string s)
{
    // Stores how many times a
    // character occurs. freqOfLetter[0]
    // stores the frequency of letter 'a'
    vector<int> freqOfLetter(26, 0);
  
    for (int i = 0; i < s.length(); i++) {
        freqOfLetter[s[i] - 'a']++;
    }
  
    // Number of characters that
    // have a given frequency
    map<int, int, greater<int> > LetterFreqMap;
  
    for (int i = 0; i < 26; i++) {
  
        // insert the frequency of
        // all lowercase letters in
        // the map that have a
        // frequency greater than 0
        if (freqOfLetter[i] != 0) {
            LetterFreqMap[freqOfLetter[i]]++;
        }
    }
  
    // Stores the number of
    // deletions needed
    int deletions = 0;
  
    // Iterate the map using
    // iterator it
    for (auto it = LetterFreqMap.begin();
         it != LetterFreqMap.end();
         it++) {
  
        // If frequency is 0
        // then all occurrences
        // have been deleted.
        if (it->first == 0)
            break;
  
        // Till more than 1
        // character has a
        // given frequency.
        while (it->second > 1) {
  
            // Delete a character
            // that has conflicting
            // frequency
            deletions++;
  
            // Now 1 less character
            // has the given frequency f
            it->second--;
  
            // But 1 more character
            // has the frequency f - 1
            LetterFreqMap[it->first - 1]++;
        }
    }
  
    return deletions;
}
  
// Driver Code
int main()
{
    string s = "geeksforgeeks";
    cout << minimumDeletions(s);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the
// approach
import java.util.*;
import java.lang.*;
import java.io.*;
  
class GFG
{
       
// Returns the mininum number
// of characters to be deleted
// so that all remaining characters
// occur unique number of times.
public static int minimumDeletions(char[] s)
{
    // Stores how many times a
    // character occurs. freqOfLetter[0]
    // stores the frequency of letter 'a'
    int[] freqOfLetter;
    freqOfLetter = new int[26];
  
    for (int i = 0; i < 26; i++)
        freqOfLetter[i] = 0;
  
    for (int i = 0; i < s.length; i++)
    {
        freqOfLetter[s[i] - 'a']++;
    }
  
    // Number of characters that
    // have a given frequency
    Map<Integer,
        Integer > LetterFreqMap = new TreeMap<Integer, 
        Integer >(Collections.reverseOrder());
  
    for (int i = 0; i < 26; i++) 
    {
  
        // insert the frequency of
        // all lowercase letters in
        // the map that have a
        // frequency greater than 0
        if (freqOfLetter[i] != 0)
        {
            if (LetterFreqMap.containsKey(freqOfLetter[i])) 
            {
                LetterFreqMap.put(freqOfLetter[i], 
                LetterFreqMap.get(freqOfLetter[i]) + 1);
            }
            else
                LetterFreqMap.put(freqOfLetter[i], 1);
        }
    }
      
    // Stores the number of
    // deletions needed
    int deletions = 0;
      
    Set<Map.Entry<Integer, 
                  Integer>> set = LetterFreqMap.entrySet();
    for (Map.Entry<Integer, Integer> me : set)
    {
  
        // If frequency is 0
        // then all occurrences
        // have been deleted.
        if (me.getKey() == 0)
            break;
  
        // Till more than 1
        // character has a
        // given frequency.
        while (me.getValue() > 1
        {
  
            // Delete a character
            // that has conflicting
            // frequency
            deletions++;
  
            // Now 1 less character
            // has the given frequency f
            LetterFreqMap.put(me.getKey(), 
            LetterFreqMap.get(me.getKey()) - 1);
  
            // But 1 more character
            // has the frequency f - 1
            if (LetterFreqMap.containsKey(me.getKey() - 1)) 
            {
                LetterFreqMap.put(me.getKey() - 1
                LetterFreqMap.get(me.getKey() - 1) + 1);
            }
            else
                LetterFreqMap.put(me.getKey() - 1, 1);
        }
    }
    return deletions;
}
  
// Driver Code
public static void main(String[] args) throws java.lang.Exception
{
    String s = "geeksforgeeks";
    System.out.println(minimumDeletions(s.toCharArray()));
}
}
  
  
// This code is contributed by ashutosh450 

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the
# approach
  
# Returns the mininum number
# of characters to be deleted
# so that all remaining characters
# occur unique number of times.
def minimumDeletions(s):
      
    # Stores how many times a
    # character occurs. freqOfLetter[0]
    # stores the frequency of letter 'a'
    freqOfLetter = [0] * 26
  
    for i in range(len(s)):
        freqOfLetter[ord(s[i]) - ord('a')] += 1
  
    # Number of characters that
    # have a given frequency
    LetterFreqMap = dict()
  
    for i in range(26):
  
        # insert the frequency of
        # all lowercase letters in
        # the map that have a
        # frequency greater than 0
        if (freqOfLetter[i] != 0):
            LetterFreqMap[freqOfLetter[i]] = \
            LetterFreqMap.get(freqOfLetter[i], 0) + 1
  
    # Stores the number of deletions needed
    deletions = 0
  
    # Iterate the map using iterator it
    a = list(LetterFreqMap.keys())
    a = a[::-1]
    for it in a:
  
        # If frequency is 0 then all occurrences
        # have been deleted.
        if (it == 0):
            break
  
        # Till more than 1 character has a
        # given frequency.
        x = LetterFreqMap[it]
        while (x > 1):
  
            # Delete a character that has 
            # conflicting frequency
            deletions += 1
  
            # Now 1 less character
            # has the given frequency f
            x -= 1
  
            # But 1 more character
            # has the frequency f - 1
            if (it - 1) in LetterFreqMap.keys():
                LetterFreqMap[it - 1] += 1
  
    return deletions
  
# Driver Code
s = "geeksforgeeks"
print(minimumDeletions(s))
  
# This code is contributed by Mohit Kumar

chevron_right


Output:

6

Time Complexity: O(n + m*m), where m = 26.

  • Counting the frequency of all characters takes O(N) time where N is the length of S.
  • Constructing the map works in O(mlogm) time, where m = 26.
  • Deletion works in O(m*m)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.