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++
// 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 characters int getIdx( char ch) { return (ch - 'a' ); } // Returns true if all non-zero elements // values are same bool 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 same bool 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 methods int main() { string str = "xyyzz" ; if (possibleSameCharFreqByOneRemoval(str)) cout << "Yes" ; else cout << "No" ; } |
Java
// Java program to get same frequency character // string by removal of at most one char public 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 |
Python 3
# Python3 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 characters def getIdx(ch): return ( ord (ch) - ord ( 'a' )) # Returns true if all non-zero elements # values are same def 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 same def 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 code if __name__ = = "__main__" : str1 = "xyyzz" if (possibleSameCharFreqByOneRemoval(str1)): print ( "Yes" ) else : print ( "No" ) # This code is contributed by Sairahul099 |
C#
// C# program to get same frequency // character string by removal of // at most one char using 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 // 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 characters function getIdx( $ch ) { return ( $ch - 'a' ); } // Returns true if all // non-zero elements // values are same function 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 same function 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" ; else echo "No" ; // This code is contributed // by ChitraNayal ?> |
Output:
Yes
Time Complexity: O(n) assuming alphabet size is constant.
This article is contributed by Utkarsh Trivedi. 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 write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
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.