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.

Updated on: 2026-03-25T19:16:27+05:30

409 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements