Given string str, the task is to find the minimum count of characters that need to be deleted from the string such that the frequency of each character of the string is unique.
Examples:
Input: str = “ceabaacb”
Output: 2
Explanation:
The frequencies of each distinct character are as follows:
c —> 2
e —> 1
a —> 3
b —> 2
Possible ways to make frequency of each character unique by minimum number of moves are:
- Removing both occurrences of ‘c’ modifies str to “eabaab”
- Removing an occurrence of ‘c’ and ‘e’ modifies str to “abaacb”
Therefore, the minimum removals required is 2.
Input: S = “abbbcccd”
Output: 2
Approach: The problem can be solved using Greedy technique. The idea is to use Map and Priority Queue. Follow the steps below to solve the problem:
- Initialize a Map, say mp, to store the frequency of each distinct character of the string.
- Initialize a variable, say cntChar to store the count of characters required to be removed to make frequency of each character of the string unique.
- Create a priority_queue, say pq to store the frequency of each character such that the largest frequency obtained is present at the top of the priority queue pq.
- Iterate over the priority_queue until pq is empty and check if the topmost of element of pq is equal to the second topmost element of pq or not. If found to be true, then decrement the value of topmost element of pq by 1 and increment the value of cntChar by 1.
- Otherwise, pop the topmost element of pq.
- Finally, print the value of cntChar.
Below is the implementation of the above approach:
C++
// C++ program to implement // the above approach #include <bits/stdc++.h> using namespace std; // Function to find the minimum count of // characters required to be deleted to make // frequencies of all characters unique int minCntCharDeletionsfrequency(string& str, int N) { // Stores frequency of each // distinct character of str unordered_map< char , int > mp; // Store frequency of each distinct // character such that the largest // frequency is present at the top priority_queue< int > pq; // Stores minimum count of characters // required to be deleted to make // frequency of each character unique int cntChar = 0; // Traverse the string for ( int i = 0; i < N; i++) { // Update frequency of str[i] mp[str[i]]++; } // Traverse the map for ( auto it : mp) { // Insert current // frequency into pq pq.push(it.second); } // Traverse the priority_queue while (!pq.empty()) { // Stores topmost // element of pq int frequent = pq.top(); // Pop the topmost element pq.pop(); // If pq is empty if (pq.empty()) { // Return cntChar return cntChar; } // If frequent and topmost // element of pq are equal if (frequent == pq.top()) { // If frequency of the topmost // element is greater than 1 if (frequent > 1) { // Insert the decremented // value of frequent pq.push(frequent - 1); } // Update cntChar cntChar++; } } return cntChar; } // Driver Code int main() { string str = "abbbcccd" ; // Stores length of str int N = str.length(); cout << minCntCharDeletionsfrequency( str, N); return 0; } |
Java
// Java program to implement // the above approach import java.util.*; class GFG{ // Function to find the minimum count of // characters required to be deleted to make // frequencies of all characters unique static int minCntCharDeletionsfrequency( char [] str, int N) { // Stores frequency of each // distinct character of str HashMap<Character, Integer> mp = new HashMap<>(); // Store frequency of each distinct // character such that the largest // frequency is present at the top PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> Integer.compare(y, x)); // Stores minimum count of characters // required to be deleted to make // frequency of each character unique int cntChar = 0 ; // Traverse the String for ( int i = 0 ; i < N; i++) { // Update frequency of str[i] if (mp.containsKey(str[i])) { mp.put(str[i], mp.get(str[i]) + 1 ); } else { mp.put(str[i], 1 ); } } // Traverse the map for (Map.Entry<Character, Integer> it : mp.entrySet()) { // Insert current // frequency into pq pq.add(it.getValue()); } // Traverse the priority_queue while (!pq.isEmpty()) { // Stores topmost // element of pq int frequent = pq.peek(); // Pop the topmost element pq.remove(); // If pq is empty if (pq.isEmpty()) { // Return cntChar return cntChar; } // If frequent and topmost // element of pq are equal if (frequent == pq.peek()) { // If frequency of the topmost // element is greater than 1 if (frequent > 1 ) { // Insert the decremented // value of frequent pq.add(frequent - 1 ); } // Update cntChar cntChar++; } } return cntChar; } // Driver Code public static void main(String[] args) { String str = "abbbcccd" ; // Stores length of str int N = str.length(); System.out.print(minCntCharDeletionsfrequency( str.toCharArray(), N)); } } // This code is contributed by Rajput-Ji |
Python3
# Python3 program to implement # the above approach # Function to find the minimum count of # characters required to be deleted to make # frequencies of all characters unique def minCntCharDeletionsfrequency( str , N): # Stores frequency of each # distinct character of str mp = {} # Store frequency of each distinct # character such that the largest # frequency is present at the top pq = [] # Stores minimum count of characters # required to be deleted to make # frequency of each character unique cntChar = 0 # Traverse the string for i in range (N): # Update frequency of str[i] mp[ str [i]] = mp.get( str [i], 0 ) + 1 # Traverse the map for it in mp: # Insert current # frequency into pq pq.append(mp[it]) pq = sorted (pq) # Traverse the priority_queue while ( len (pq) > 0 ): # Stores topmost # element of pq frequent = pq[ - 1 ] # Pop the topmost element del pq[ - 1 ] # If pq is empty if ( len (pq) = = 0 ): # Return cntChar return cntChar # If frequent and topmost # element of pq are equal if (frequent = = pq[ - 1 ]): # If frequency of the topmost # element is greater than 1 if (frequent > 1 ): # Insert the decremented # value of frequent pq.append(frequent - 1 ) # Update cntChar cntChar + = 1 pq = sorted (pq) return cntChar # Driver Code if __name__ = = '__main__' : str = "abbbcccd" # Stores length of str N = len ( str ) print (minCntCharDeletionsfrequency( str , N)) # This code is contributed by mohit kumar 29 |
C#
// C# program to implement // the above approach using System; using System.Collections.Generic; class GFG{ // Function to find the minimum count of // characters required to be deleted to make // frequencies of all characters unique static int minCntCharDeletionsfrequency( char [] str, int N) { // Stores frequency of each // distinct character of str Dictionary< char , int > mp = new Dictionary< char , int >(); // Store frequency of each distinct // character such that the largest // frequency is present at the top List< int > pq = new List< int >(); // Stores minimum count of characters // required to be deleted to make // frequency of each character unique int cntChar = 0; // Traverse the String for ( int i = 0; i < N; i++) { // Update frequency of str[i] if (mp.ContainsKey(str[i])) { mp[str[i]]++; } else { mp.Add(str[i], 1); } } // Traverse the map foreach (KeyValuePair< char , int > it in mp) { // Insert current // frequency into pq pq.Add(it.Value); } pq.Sort(); pq.Reverse(); // Traverse the priority_queue while (pq.Count != 0) { // Stores topmost // element of pq pq.Sort(); pq.Reverse(); int frequent = pq[0]; // Pop the topmost element pq.RemoveAt(0); // If pq is empty if (pq.Count == 0) { // Return cntChar return cntChar; } // If frequent and topmost // element of pq are equal if (frequent == pq[0]) { // If frequency of the topmost // element is greater than 1 if (frequent > 1) { // Insert the decremented // value of frequent pq.Add(frequent - 1); pq.Sort(); // pq.Reverse(); } // Update cntChar cntChar++; } } return cntChar; } // Driver Code public static void Main(String[] args) { String str = "abbbcccd" ; // Stores length of str int N = str.Length; Console.Write(minCntCharDeletionsfrequency( str.ToCharArray(), N)); } } // This code is contributed by shikhasingrajput |
2
Time Complexity:O(N)
Auxiliary Space:O(256)
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.