Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Python dictionary, set and counter to check if frequencies can become same
When working with character frequencies in strings, we often need to check if all characters can have the same frequency with minimal changes. This problem can be solved using Python's Counter from the collections module to count frequencies, then analyzing the frequency distribution.
Understanding the Problem
The goal is to determine if we can make all character frequencies equal by removing at most one character. For example, in "xxxyyyzzzzzz", we have frequencies [3, 3, 6] which cannot be made equal with just one removal.
Solution Using Counter and Set
Here's how we can solve this problem step by step ?
from collections import Counter
def check_frequencies_can_be_same(text):
# Count frequency of each character
freq_counter = Counter(text)
# Get unique frequency values
unique_frequencies = list(set(freq_counter.values()))
# Check different cases
if len(unique_frequencies) > 2:
return "Frequencies cannot be made same"
elif len(unique_frequencies) == 2 and unique_frequencies[1] - unique_frequencies[0] > 1:
return "Frequencies cannot be made same"
else:
return "Frequencies can be made same"
# Test with different strings
test_string = "xxxyyyzzzzzz"
print(f"String: {test_string}")
print(f"Result: {check_frequencies_can_be_same(test_string)}")
String: xxxyyyzzzzzz Result: Frequencies cannot be made same
How the Algorithm Works
Let's trace through the algorithm with a detailed example ?
from collections import Counter
def analyze_frequencies(text):
# Step 1: Count character frequencies
freq_counter = Counter(text)
print(f"Character frequencies: {dict(freq_counter)}")
# Step 2: Get unique frequency values
unique_frequencies = list(set(freq_counter.values()))
unique_frequencies.sort() # Sort for easier analysis
print(f"Unique frequencies: {unique_frequencies}")
# Step 3: Apply logic
if len(unique_frequencies) > 2:
print("More than 2 different frequencies - impossible to equalize")
return False
elif len(unique_frequencies) == 2:
diff = unique_frequencies[1] - unique_frequencies[0]
print(f"Two frequencies with difference: {diff}")
if diff > 1:
print("Difference too large - cannot equalize")
return False
print("Frequencies can be made equal!")
return True
# Test cases
test_cases = ["aabbcc", "aaabbc", "xxxyyyzzzzzz"]
for test in test_cases:
print(f"\n--- Analyzing: '{test}' ---")
analyze_frequencies(test)
--- Analyzing: 'aabbcc' ---
Character frequencies: {'a': 2, 'b': 2, 'c': 2}
Unique frequencies: [2]
Frequencies can be made equal!
--- Analyzing: 'aaabbc' ---
Character frequencies: {'a': 3, 'b': 2, 'c': 1}
Unique frequencies: [1, 2, 3]
More than 2 different frequencies - impossible to equalize
--- Analyzing: 'xxxyyyzzzzzz' ---
Character frequencies: {'x': 3, 'y': 3, 'z': 6}
Unique frequencies: [3, 6]
Two frequencies with difference: 3
Difference too large - cannot equalize
Key Logic Rules
The algorithm follows these rules ?
| Case | Condition | Result | Example |
|---|---|---|---|
| All same | 1 unique frequency | Already equal | "aabbcc" ? [2] |
| Two close frequencies | 2 frequencies, diff ? 1 | Can be equalized | "aabbc" ? [2,3] |
| Two distant frequencies | 2 frequencies, diff > 1 | Cannot be equalized | "abbcccc" ? [1,4] |
| Many frequencies | > 2 unique frequencies | Cannot be equalized | "abcde" ? [1,1,1,1,1] |
Optimized Version
Here's a cleaner, more efficient version ?
from collections import Counter
def can_equalize_frequencies(text):
frequencies = list(Counter(text).values())
unique_freqs = sorted(set(frequencies))
# Case 1: Already equal
if len(unique_freqs) == 1:
return True
# Case 2: Two different frequencies
if len(unique_freqs) == 2:
return unique_freqs[1] - unique_freqs[0] <= 1
# Case 3: More than 2 different frequencies
return False
# Test the optimized version
test_strings = ["hello", "aabbcc", "abcdef", "aaabbc"]
for string in test_strings:
result = can_equalize_frequencies(string)
frequencies = dict(Counter(string))
print(f"'{string}' {frequencies} ? {'Yes' if result else 'No'}")
'hello' {'h': 1, 'e': 1, 'l': 2, 'o': 1} ? No
'aabbcc' {'a': 2, 'b': 2, 'c': 2} ? Yes
'abcdef' {'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1, 'f': 1} ? Yes
'aaabbc' {'a': 3, 'b': 2, 'c': 1} ? No
Conclusion
This solution uses Counter to efficiently count character frequencies, then analyzes the frequency distribution. The key insight is that frequencies can be equalized only if there are at most 2 unique frequency values with a difference of 1 or less.
