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
Check if a string has all characters with same frequency with one variation allowed in Python
Sometimes we need to check if a string can become "valid" by removing at most one character. A valid string means all unique characters have the same frequency. For example, "aab" is not valid (a appears 2 times, b appears 1 time), but we can remove one 'a' to make it "ab" where both characters appear once.
Problem Example
Given string s = "xyyzx", we can delete one 'z' to get "xyyx" where both 'x' and 'y' appear twice ?
Approach
The algorithm counts character frequencies and checks if we can achieve uniform frequency by removing at most one character. It tracks two possible frequency values and counts how many characters have each frequency.
Implementation
def can_make_valid(s):
# Count frequency of each character
freq = {}
for char in s:
freq[char] = freq.get(char, 0) + 1
# Get all frequency values
frequencies = list(freq.values())
freq_count = {}
# Count how many characters have each frequency
for f in frequencies:
freq_count[f] = freq_count.get(f, 0) + 1
# Get unique frequency values
unique_freqs = list(freq_count.keys())
# Case 1: All characters already have same frequency
if len(unique_freqs) == 1:
freq_val = unique_freqs[0]
# Valid if frequency is 1, or we can remove 1 char from any character
return freq_val == 1 or freq_count[freq_val] == 1
# Case 2: Exactly two different frequencies
if len(unique_freqs) == 2:
freq1, freq2 = unique_freqs[0], unique_freqs[1]
count1, count2 = freq_count[freq1], freq_count[freq2]
# Can remove one character to make all frequencies equal
if (freq1 == freq2 + 1 and count1 == 1) or \
(freq2 == freq1 + 1 and count2 == 1) or \
(freq1 == 1 and count1 == 1) or \
(freq2 == 1 and count2 == 1):
return True
return False
# Test examples
test_cases = ["xyyzx", "abc", "aab", "aabc"]
for s in test_cases:
result = can_make_valid(s)
print(f"'{s}' -> {result}")
The output shows whether each string can be made valid ?
'xyyzx' -> True 'abc' -> True 'aab' -> True 'aabc' -> False
How It Works
The solution works by analyzing frequency patterns:
- Count frequencies: Build a frequency map for all characters
- Analyze frequency distribution: Count how many characters have each frequency value
-
Check validity conditions:
- All same frequency: Valid if frequency is 1 or only one character type exists
- Two frequencies: Valid if we can remove one character to equalize frequencies
- More than two frequencies: Invalid (can't fix with one deletion)
Alternative Simplified Approach
def is_valid_with_one_deletion(s):
from collections import Counter
# Count character frequencies
char_freq = Counter(s)
freq_count = Counter(char_freq.values())
# If only one unique frequency, check special cases
if len(freq_count) == 1:
freq = list(freq_count.keys())[0]
return freq == 1 or len(char_freq) == 1
# If exactly two frequencies, check if we can fix by removing one char
if len(freq_count) == 2:
freqs = sorted(freq_count.keys())
low_freq, high_freq = freqs[0], freqs[1]
low_count, high_count = freq_count[low_freq], freq_count[high_freq]
# Valid cases for two frequencies
return ((high_freq - low_freq == 1 and high_count == 1) or
(low_freq == 1 and low_count == 1) or
(high_freq == 1 and high_count == 1))
return False
# Test the function
s = "xyyzx"
print(f"Can make '{s}' valid: {is_valid_with_one_deletion(s)}")
Can make 'xyyzx' valid: True
Conclusion
To check if a string can be made valid with one deletion, count character frequencies and analyze the frequency distribution. The string is valid if all characters have the same frequency or if removing one character can achieve uniform frequency.
