Check if frequency of all characters can become same by one removal - GeeksforGeeks

22 Nov, 2021
Given a string which contains lower alphabetic characters, we need to remove at most one character from this string in such a way that frequency of each distinct character becomes same in the string.
Examples:  
Input: str = “xyyz” Output: Yes We can remove character ’y’ from above string to make the frequency of each character same. 
Input: str = “xyyzz” Output: Yes We can remove character ‘x’ from above string to make the frequency of each character same.
Input: str = “xxxxyyzz” Output: No It is not possible to make frequency of each character same just by removing at most one character from above string.
Approach: The problem can be solved using the concept of hashing. The main thing to observe in this problem is that the position of characters does not matter here so we will count the frequency of characters, if all of them are the same then we are done and there is no need to remove any character to make frequency of characters same Otherwise we can iterate over all characters one by one and decrease their frequency by one, if all frequencies become same then we will flag that it is possible to make character frequency same by at most one removal and if frequencies don’t match then we will increase that frequency again and loop for other characters. 
Below is a dry run of the above approach: 
Below is the implementation of the above approach:
C++
Java
Python3
C#
PHP
Javascript
// C++ program to get same frequency character// string by removal of at most one char#include <bits/stdc++.h>using namespace std;#define M 26 // Utility method to get index of character ch// in lower alphabet charactersint getIdx(char ch){    return (ch - 'a');} // Returns true if all non-zero elements// values are samebool allSame(int freq[], int N){    int same;     // get first non-zero element    int i;    for (i = 0; i < N; i++) {        if (freq[i] > 0) {            same = freq[i];            break;        }    }     // check equality of each element with variable same    for (int j = i + 1; j < N; j++)        if (freq[j] > 0 && freq[j] != same)            return false;     return true;} // Returns true if we can make all character// frequencies samebool possibleSameCharFreqByOneRemoval(string str){    int l = str.length();     // fill frequency array    int freq[M] = { 0 };    for (int i = 0; i < l; i++)        freq[getIdx(str[i])]++;     // if all frequencies are same, then return true    if (allSame(freq, M))        return true;     /*  Try decreasing frequency of all character        by one and then    check all equality of all        non-zero frequencies */    for (char c = 'a'; c <= 'z'; c++) {        int i = getIdx(c);         // Check character only if it occurs in str        if (freq[i] > 0) {            freq[i]--;             if (allSame(freq, M))                return true;            freq[i]++;        }    }     return false;} // Driver code to test above methodsint main(){    string str = "xyyzz";    if (possibleSameCharFreqByOneRemoval(str))        cout << "Yes";    else        cout << "No";}
// Java program to get same frequency character// string by removal of at most one charpublic class GFG {     static final int M = 26;     // Utility method to get index of character ch    // in lower alphabet characters    static int getIdx(char ch)    {        return (ch - 'a');    }     // Returns true if all non-zero elements    // values are same    static boolean allSame(int freq[], int N)    {        int same = 0;         // get first non-zero element        int i;        for (i = 0; i < N; i++) {            if (freq[i] > 0) {                same = freq[i];                break;            }        }         // check equality of each element with        // variable same        for (int j = i + 1; j < N; j++)            if (freq[j] > 0 && freq[j] != same)                return false;         return true;    }     // Returns true if we can make all character    // frequencies same    static boolean possibleSameCharFreqByOneRemoval(String str)    {        int l = str.length();         // fill frequency array        int[] freq = new int[M];         for (int i = 0; i < l; i++)            freq[getIdx(str.charAt(i))]++;         // if all frequencies are same, then return true        if (allSame(freq, M))            return true;         /*  Try decreasing frequency of all character            by one and then check all equality of all            non-zero frequencies */        for (char c = 'a'; c <= 'z'; c++) {            int i = getIdx(c);             // Check character only if it occurs in str            if (freq[i] > 0) {                freq[i]--;                 if (allSame(freq, M))                    return true;                freq[i]++;            }        }         return false;    }     // Driver code to test above methods    public static void main(String args[])    {        String str = "xyyzz";        if (possibleSameCharFreqByOneRemoval(str))            System.out.println("Yes");        else            System.out.println("No");    }}// This code is contributed by Sumit Ghosh
# Python3 program to get same frequency character# string by removal of at most one charM = 26 # Utility method to get index of character ch# in lower alphabet charactersdef getIdx(ch):    return (ord(ch) - ord('a')) # Returns true if all non-zero elements# values are samedef allSame(freq, N):         # get first non-zero element    for i in range(0, N):        if(freq[i] > 0):            same = freq[i]            break             # check equality of each element    # with variable same        for j in range(i + 1, N):        if(freq[j] > 0 and freq[j] != same):            return False     return True # Returns true if we can make all# character frequencies samedef possibleSameCharFreqByOneRemoval(str1):    l = len(str1)     # fill frequency array    freq = [0] * M    for i in range(0, l):        freq[getIdx(str1[i])] += 1             # if all frequencies are same,    # then return true    if(allSame(freq, M)):        return True         # Try decreasing frequency of all character    # by one and then check all equality of all    # non-zero frequencies    for i in range(0, 26):                 # Check character only if it        # occurs in str        if(freq[i] > 0):            freq[i] -= 1             if(allSame(freq, M)):                return True            freq[i] += 1     return False # Driver codeif __name__ == "__main__":    str1 = "xyyzz"    if(possibleSameCharFreqByOneRemoval(str1)):        print("Yes")    else:        print("No") # This code is contributed by Sairahul099
// C# program to get same frequency// character string by removal of// at most one charusing System; class GFG {    static int M = 26;     // Utility method to get    // index of character ch    // in lower alphabet characters    static int getIdx(char ch)    {        return (ch - 'a');    }     // Returns true if all    // non-zero elements    // values are same    static bool allSame(int[] freq,                        int N)    {        int same = 0;         // get first non-zero element        int i;        for (i = 0; i < N; i++) {            if (freq[i] > 0) {                same = freq[i];                break;            }        }         // check equality of        // each element with        // variable same        for (int j = i + 1; j < N; j++)            if (freq[j] > 0 && freq[j] != same)                return false;         return true;    }     // Returns true if we    // can make all character    // frequencies same    static bool possibleSameCharFreqByOneRemoval(string str)    {        int l = str.Length;         // fill frequency array        int[] freq = new int[M];         for (int i = 0; i < l; i++)            freq[getIdx(str[i])]++;         // if all frequencies are same,        // then return true        if (allSame(freq, M))            return true;         /* Try decreasing frequency of all            character by one and then check            all equality of all non-zero            frequencies */        for (char c = 'a'; c <= 'z'; c++) {            int i = getIdx(c);             // Check character only if            // it occurs in str            if (freq[i] > 0) {                freq[i]--;                 if (allSame(freq, M))                    return true;                freq[i]++;            }        }         return false;    }     // Driver code    public static void Main()    {        string str = "xyyzz";        if (possibleSameCharFreqByOneRemoval(str))            Console.Write("Yes");        else            Console.Write("No");    }} // This code is contributed// by ChitraNayal
<?php// PHP program to get same frequency// character string by removal of at// most one char$M = 26; // Utility method to get index// of character ch in lower// alphabet charactersfunction getIdx($ch){    return ($ch - 'a');} // Returns true if all// non-zero elements// values are samefunction allSame(&$freq, $N){    // get first non-zero element    for ($i = 0; $i < $N; $i++)    {        if ($freq[$i] > 0)        {            $same = $freq[$i];            break;        }    }     // check equality of each    // element with variable same    for ($j = $i + 1; $j < $N; $j++)        if ($freq[$j] > 0 &&            $freq[$j] != $same)            return false;     return true;} // Returns true if we// can make all character// frequencies samefunction possibleSameCharFreqByOneRemoval($str){    global $M;    $l = strlen($str);     // fill frequency array    $freq = array_fill(0, $M, NULL);    for ($i = 0; $i < $l; $i++)        $freq[getIdx($str[$i])]++;     // if all frequencies are same,    // then return true    if (allSame($freq, $M))        return true;     /* Try decreasing frequency of all        character by one and then check        all equality of all non-zero        frequencies */    for ($c = 'a'; $c <= 'z'; $c++)    {        $i = getIdx($c);         // Check character only        // if it occurs in str        if ($freq[$i] > 0)        {            $freq[$i]--;             if (allSame($freq, $M))                return true;            $freq[$i]++;        }    }     return false;} // Driver code$str = "xyyzz";if (possibleSameCharFreqByOneRemoval($str))echo "Yes";elseecho "No"; // This code is contributed// by ChitraNayal?>
<script> // Javascript program to get same// frequency character string by// removal of at most one charlet  M = 26; // Utility method to get index of character// ch in lower alphabet charactersfunction getIdx(ch){    return (ch - 'a');} // Returns true if all non-zero elements// values are samefunction allSame(freq, N){    let same = 0;     // Get first non-zero element    let i;    for(i = 0; i < N; i++)    {        if (freq[i] > 0)        {            same = freq[i];            break;        }    }     // Check equality of each element with    // variable same    for(let j = i + 1; j < N; j++)        if (freq[j] > 0 && freq[j] != same)            return false;     return true;} // Returns true if we can make all character// frequencies samefunction possibleSameCharFreqByOneRemoval(str){    let l = str.length;     // Fill frequency array    let freq = new Array(M);    for(let i = 0; i < M; i++)    {        freq[i] = 0;    }     for(let i = 0; i < l; i++)        freq[getIdx(str[i])]++;     // If all frequencies are same,    // then return true    if (allSame(freq, M))        return true;     // Try decreasing frequency of all character    // by one and then check all equality of all    // non-zero frequencies    for(let c = 'a'; c <= 'z'; c++)    {        let i = getIdx(c);         // Check character only if        // it occurs in str        if (freq[i] > 0)        {            freq[i]--;             if (allSame(freq, M))                return true;                             freq[i]++;        }    }    return false;} // Driver codelet str = "xyyzz"; if (possibleSameCharFreqByOneRemoval(str))    document.write("Yes");else    document.write("No"); // This code is contributed by avanitrachhadiya2155 </script>
Output: 
Yes
Time Complexity: O(n) assuming alphabet size is constant. 
Auxiliary Space: O(26) 
YouTubeGeeksforGeeks500K subscribersCheck if frequency of all characters can become same by one removal | GeeksforGeeksWatch laterShareCopy linkInfoShoppingTap to unmuteIf playback doesn't begin shortly, try restarting your device.You're signed outVideos you watch may be added to the TV's watch history and influence TV recommendations. To avoid this, cancel and sign in to YouTube on your computer.CancelConfirmMore videosMore videosSwitch cameraShareInclude playlistAn error occurred while retrieving sharing information. Please try again later.Watch on0:000:000:00 / 3:19•Live•<div class="player-unavailable"><h1 class="message">An error occurred.</h1><div class="submessage"><a href="https://www.youtube.com/watch?v=unw9XO7vUYQ" target="_blank">Try watching this video on www.youtube.com</a>, or enable JavaScript if it is disabled in your browser.</div></div>
This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
ukasp
Sairahul Jella
avanitrachhadiya2155
rohitkumarsinghcna
Hash
Strings
Hash
Strings
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Most frequent element in an array
Counting frequencies of array elements
Double Hashing
Quadratic Probing in Hashing
Implementing our Own Hash Table with Separate Chaining in Java
Reverse a string in Java
Write a program to reverse an array or string
C++ Data Types
Write a program to print all permutations of a given string
Check for Balanced Brackets in an expression (well-formedness) using Stack