问题描述
我们需要计算一个由字符 'c' 和 'h' 组成的字符串的所有子串中,包含目标子串 "chhc" 的总次数。这些子串的总权值就是我们需要求解的结果。
解题思路
-
生成所有子串:
- 遍历字符串,生成所有可能的子串。
-
计算目标子串出现次数:
- 对每个子串,统计其中包含目标子串
"chhc"的次数。可以使用find方法从左到右搜索目标子串。
- 对每个子串,统计其中包含目标子串
-
累计权值:
- 对每个子串的统计结果进行累加,得到所有子串中目标子串出现次数的总和。
数据结构
-
双重循环生成子串:
- 使用两个嵌套循环来生成所有子串。
- 外层循环确定子串的起始位置,内层循环确定子串的结束位置。
-
搜索子串:
- 对于每个生成的子串,使用
find方法从左到右统计目标子串"chhc"的出现次数。
- 对于每个生成的子串,使用
算法步骤
-
初始化总计数器
total_count。 -
使用两层循环生成所有可能的子串:
- 外层循环从字符串的起始位置开始。
- 内层循环从外层的起点延伸到字符串末尾,生成子串。
-
对每个子串,使用
find方法统计"chhc"出现的次数。 -
累加每个子串中统计的结果。
-
返回累加结果
total_count。
时间复杂度分析
- 生成所有子串:双重循环生成子串的复杂度为 O(n2)O(n^2),其中 nn 是字符串的长度。
- 统计子串中目标子串的出现次数:对每个子串,最坏情况下需要 O(n)O(n) 的时间。
- 总复杂度:最坏情况下,复杂度为 O(n3)O(n^3)。
尽管时间复杂度较高,但可以满足小规模输入要求。
实现代码
以下是实现该逻辑的 Python 代码:
def solution(s):
target = "chhc"
total_count = 0
n = len(s)
# 遍历所有子串
for i in range(n):
for j in range(i + 1, n + 1):
substring = s[i:j]
count = 0
start = 0
# 统计目标子串 "chhc" 出现次数
while True:
start = substring.find(target, start)
if start == -1:
break
count += 1
start += 1
total_count += count
return total_count
# 测试代码
if __name__ == '__main__':
print(solution("chhchhc") == 8) # 样例1
print(solution("chhcchhcchhc") == 43) # 样例2
print(solution("hhhh") == 0) # 样例3
测试分析
测试样例 1
输入:
s = "chhchhc"
分析:
- 所有子串中,目标子串
"chhc"出现 8 次。 - 输出应为 8。
输出:
8
测试样例 2
输入:
s = "chhcchhcchhc"
分析:
- 所有子串中,目标子串
"chhc"出现 43 次。 - 输出应为 43。
输出:
43
测试样例 3
输入:
s = "hhhh"
分析:
- 字符串不包含目标子串
"chhc",因此总权值为 0。 - 输出应为 0。
输出:
0
改进思路
尽管上述方法能正确解决问题,但由于时间复杂度较高,不适合大规模字符串输入。以下是两种可能的优化思路:
-
直接查找目标子串:
- 遍历字符串,仅检查从当前位置开始长度为 4 的子串是否等于
"chhc"。 - 遇到匹配时计数,减少无关子串的生成。
- 遍历字符串,仅检查从当前位置开始长度为 4 的子串是否等于
-
动态规划:
- 使用动态规划记录从某个起点开始的子串是否包含
"chhc",避免重复计算。
- 使用动态规划记录从某个起点开始的子串是否包含
个人总结
- 基础方法:使用双重循环生成所有子串,然后统计目标子串的出现次数,逻辑清晰但效率较低。
- 优化方向:通过滑动窗口或动态规划等方式减少重复计算,提高大规模输入的适应能力。