问题解析
题目要求我们通过最小的替换次数,使得一个字符串中的字符 A、S、D、F 四个字符出现的频次相等。题目给出的字符串长度总是 4 的倍数,因此每个字符应该出现在字符串中的频次是相等的,即 n // 4(其中 n 是字符串的长度)。
问题思路
-
计数频次:
- 先计算每个字符
A、S、D、F在字符串中的出现次数。
- 先计算每个字符
-
确定目标频次:
- 目标是让每个字符的出现次数达到
n // 4,其中n是字符串的长度。
- 目标是让每个字符的出现次数达到
-
找出不平衡的部分:
- 对于每个字符,我们需要知道其出现次数与目标次数之间的差值。大于目标次数的部分是过多的字符,少于目标次数的部分是需要增加的字符。
-
使用最小替换:
- 通过最小替换,我们可以把过多的字符替换成缺失的字符。我们要计算最少的替换次数,这就是题目要求的最小子串长度。
详细步骤
- 计算每个字符的出现次数。
- 确定每个字符的目标频次。
- 计算缺失字符的数量和过多字符的数量。
- 通过最小替换使得每个字符的频次相等,并计算最小替换的子串长度。
代码实现
pythonCopy Code
from collections import Counter
def minReplaceSubstr(input):
n = len(input)
target_freq = n // 4 # 每个字符的目标频次
count = Counter(input) # 计算每个字符的频次
# 计算过多的字符和缺少的字符
excess = {}
deficit = {}
# 遍历每个字符,计算是否有过多或缺少
for char in 'ASDF':
if count[char] > target_freq:
excess[char] = count[char] - target_freq
elif count[char] < target_freq:
deficit[char] = target_freq - count[char]
# 若没有过多或缺少的字符,直接返回0
if not excess and not deficit:
return 0
# 最小替换次数就是把过多的字符替换为缺少的字符
replacements = 0
for char in excess:
excess_count = excess[char]
# 从缺少的字符中去替换
for dchar in deficit:
if deficit[dchar] > 0:
# 计算替换次数
to_replace = min(excess_count, deficit[dchar])
replacements += to_replace
excess_count -= to_replace
deficit[dchar] -= to_replace
if excess_count == 0:
break
return replacements
# 测试样例
print(minReplaceSubstr("ADDF")) # 输出: 1
print(minReplaceSubstr("ASAFASAFADDD")) # 输出: 3
print(minReplaceSubstr("SSDDFFFFAAAS")) # 输出: 1
print(minReplaceSubstr("AAAASSSSDDDDFFFF")) # 输出: 0
print(minReplaceSubstr("AAAADDDDAAAASSSS")) # 输出: 4
代码解析
-
Counter类的使用:- 使用
Counter来统计字符串中每个字符的出现次数。count = Counter(input)会返回一个字典,其中键是字符,值是该字符出现的次数。
- 使用
-
计算目标频次:
target_freq = n // 4是每个字符应该出现的目标频次,n是字符串的长度。
-
计算过多字符与缺少字符:
- 通过比较字符的出现次数与目标频次,找到每个字符是否过多或缺少。
-
计算最小替换次数:
- 遍历所有过多字符,将它们替换为缺少的字符。每次替换一个字符,直到所有缺少的字符被填补。
-
替换操作:
- 对于每一个过多字符,查找缺少字符并尽量进行替换。每次替换一个字符,直到所有缺少的字符的需求被满足。
样例解析
-
样例1:
"ADDF"- 字符出现次数:
A: 1, D: 2, F: 1 - 目标频次是
1。D需要减少1次,而A和F需要增加各自的次数。 - 最少替换次数是
1。
- 字符出现次数:
-
样例2:
"ASAFASAFADDD"- 字符出现次数:
A: 4, S: 2, D: 3, F: 1 - 目标频次是
3。A多出1次,D多出1次,F少2次,S少1次。 - 需要替换
F和S,最少替换次数是3。
- 字符出现次数:
-
样例3:
"SSDDFFFFAAAS"- 字符出现次数:
S: 4, D: 2, F: 4, A: 2 - 目标频次是
3。S和F过多,A和D缺少。 - 最少替换次数是
1。
- 字符出现次数:
-
样例4:
"AAAASSSSDDDDFFFF"- 字符出现次数:
A: 4, S: 4, D: 4, F: 4 - 每个字符的出现次数已经相等,不需要任何替换,输出
0。
- 字符出现次数:
-
样例5:
"AAAADDDDAAAASSSS"- 字符出现次数:
A: 7, D: 4, S: 3, F: 0 - 目标频次是
4。A过多,S和F缺少。 - 最少替换次数是
4。
- 字符出现次数:
学习总结
-
字符串频率统计:
Counter是一个非常方便的工具,用来统计字符串或列表中元素的频率,非常适合解决类似题目。
-
贪心策略:
- 题目通过最少替换的方式,将过多字符替换为缺少字符,实际上是应用了贪心策略。每次都用最少的替换填补缺失。
-
实践建议:
- 对于这种类型的问题,可以通过先统计字符频率,再进行替换操作来高效解决。保证操作的简单性和清晰性。
学习计划
-
熟悉贪心算法:
- 贪心算法是处理最优化问题的一个重要思路,通过最优选择来逐步解决问题。深入理解贪心策略在实际问题中的应用。
-
刷题技巧:
- 通过分析错题,总结解题的思路,并应用到其他题目中。可以通过将解题方法整理成笔记,便于以后复习和提升。
-
高效学习法:
- 制定每天的学习计划,定期复习总结,尽量避免死记硬背,理解每种算法的本质,并通过实践提高自己的问题解决能力。
工具运用
结合AI刷题工具如豆包MarsCode AI平台,不仅可以快速获得题目的解法,还可以通过社区讨论和题解交流,提升对算法的理解和应用。通过错题回顾和总结,帮助自己不断优化代码和解题思路。