Given a string S of length n, consisting of lowercase English letters. The task is to check if it is possible to remove at most K letter from S such that the frequency of every remaining letter is equal.
Examples:
Input: S = "aabbcc", K = 2
Output: True
Explanation: We can remove one 'a' and one 'b' to get "abbcc", where the frequency of each remaining letter is 2Input: S = "eaabbccd", K = 1
Output: False
Explanation: Removing any one letter won't be enough to make the frequency of every remaining letter equal.
Approach:
The goal is to see if we can remove up to K letters to make all remaining letters in S have the same frequency. To achieve this, we can follow these steps:
- Count the frequency of each letter in the string.
- Determine the unique frequencies of these counts.
- Analyze if adjusting these frequencies by removing up to K letters can make the frequencies equal.
Step-by-Step Approach:
- Count the frequency of each character in the string S.
- Record the frequencies in a map or array.
- Determine the unique frequency values.
- Check if you can make all frequencies equal by removing at most K letters:
- If there's only one unique frequency, return
True. - If there are two unique frequencies, check the conditions under which you can adjust them to become equal by removing up to K letters.
- If more than two unique frequencies exist, it's not possible to equalize them by removing K letters, return
False.
- If there's only one unique frequency, return
Below is the implementation of the above approach:
#include <bits/stdc++.h>
using namespace std;
bool canMakeEqualFrequency(string S, int K)
{
unordered_map<char, int> frequencyMap;
// Count frequency of each character
for (char c : S) {
frequencyMap[c]++;
}
// Store frequencies in a vector
vector<int> frequencies;
for (auto entry : frequencyMap) {
frequencies.push_back(entry.second);
}
// Sort frequencies to easily check the conditions
sort(frequencies.begin(), frequencies.end());
// If all frequencies are already the same
if (frequencies.front() == frequencies.back()) {
return true;
}
// We now check two cases: reducing the higher frequency
// or increasing the lower frequency
int minFreq = frequencies.front();
int maxFreq = frequencies.back();
// Case 1: Remove characters to reduce the higher
// frequency
int removeMaxFreq = maxFreq - minFreq;
int maxFreqCount = count(frequencies.begin(),
frequencies.end(), maxFreq);
if ((removeMaxFreq * maxFreqCount <= K)
&& (frequencies[frequencies.size() - maxFreqCount
- 1]
== minFreq)) {
return true;
}
// Case 2: Remove characters to increase the lower
// frequency
int minFreqCount = count(frequencies.begin(),
frequencies.end(), minFreq);
if ((minFreq * minFreqCount <= K)
&& (frequencies[minFreqCount] == maxFreq)) {
return true;
}
return false;
}
int main()
{
string S1 = "aabbcc";
int K1 = 2;
cout << "Example 1: "
<< (canMakeEqualFrequency(S1, K1) ? "True"
: "False")
<< endl;
string S2 = "eaabbccd";
int K2 = 1;
cout << "Example 2: "
<< (canMakeEqualFrequency(S2, K2) ? "True"
: "False")
<< endl;
return 0;
}
import java.util.*;
public class Main {
public static boolean canMakeEqualFrequency(String S, int K) {
// Count frequency of each character
Map<Character, Integer> frequencyMap = new HashMap<>();
for (char c : S.toCharArray()) {
frequencyMap.put(c, frequencyMap.getOrDefault(c, 0) + 1);
}
// Store frequencies in a list
List<Integer> frequencies = new ArrayList<>(frequencyMap.values());
Collections.sort(frequencies);
// If all frequencies are already the same
if (frequencies.get(0).equals(frequencies.get(frequencies.size() - 1))) {
return true;
}
// We now check two cases: reducing the higher frequency or increasing the lower frequency
int minFreq = frequencies.get(0);
int maxFreq = frequencies.get(frequencies.size() - 1);
// Case 1: Remove characters to reduce the higher frequency
int removeMaxFreq = maxFreq - minFreq;
int maxFreqCount = Collections.frequency(frequencies, maxFreq);
if ((removeMaxFreq * maxFreqCount <= K) && (frequencies.get(frequencies.size() - maxFreqCount - 1) == minFreq)) {
return true;
}
// Case 2: Remove characters to increase the lower frequency
int minFreqCount = Collections.frequency(frequencies, minFreq);
if ((minFreq * minFreqCount <= K) && (frequencies.get(minFreqCount) == maxFreq)) {
return true;
}
return false;
}
public static void main(String[] args) {
String S1 = "aabbcc";
int K1 = 2;
System.out.println("Example 1: " + (canMakeEqualFrequency(S1, K1) ? "True" : "False"));
String S2 = "eaabbccd";
int K2 = 1;
System.out.println("Example 2: " + (canMakeEqualFrequency(S2, K2) ? "True" : "False"));
}
}
// This code is contributed by Shivam Gupta
Output
Example 1: True Example 2: False
Time Complexity: O(n + m*logm) Counting frequencies takes O(n). Sorting the frequencies takes O(m*logm) where m is the number of unique characters (at most 26 for lowercase English letters).
Auxiliary Space: O(m) The frequency map and the vector to store frequencies both use O(m) space.