Python代码优化:(L,t)-clump字符串问题求解方案问询
嘿,我来帮你把这个(L,t)-clump的解法打磨得更高效清晰!你的滑动窗口思路完全没问题,咱们把它落地成优化后的Python代码,再一步步拆解说明。
核心思路回顾
咱们的核心逻辑是用滑动窗口维护长度为L的区间,同时跟踪窗口内所有长度为k的子串的出现次数:
- 先初始化第一个长度为L的窗口,统计其中所有k长子串的出现次数
- 每次将窗口向右滑动一位:移除窗口左端被淘汰的k长子串,加入窗口右端新增的k长子串
- 每次更新计数后,检查是否有子串的出现次数≥t,收集这些符合条件的子串(自动去重)
优化后的Python代码
from collections import defaultdict def find_clumps(s, L, t, k): clumps = set() n = len(s) # 边界情况处理:直接过滤不可能形成clump的场景 if k > L or L > n or t <= 0: return clumps # 初始化第一个窗口的子串计数 count = defaultdict(int) # 第一个窗口内的k长子串共有 L - k + 1 个 for i in range(L - k + 1): substr = s[i:i+k] count[substr] += 1 # 检查第一个窗口是否有符合条件的clump for substr, cnt in count.items(): if cnt >= t: clumps.add(substr) # 滑动窗口处理后续所有区间 for start in range(1, n - L + 1): # 移除窗口左端被淘汰的旧子串 left_substr = s[start-1 : start-1 + k] count[left_substr] -= 1 if count[left_substr] == 0: del count[left_substr] # 清理计数为0的键,节省空间 # 添加窗口右端新增的子串 right_substr_start = start + L - k right_substr = s[right_substr_start : right_substr_start + k] count[right_substr] += 1 # 检查当前窗口是否有新的符合条件的clump if count[right_substr] >= t: clumps.add(right_substr) return clumps
代码细节拆解
- 边界处理:先过滤掉无意义的输入场景,比如k>L(k长子串没法在L长区间里出现哪怕1次)、L超过字符串长度(没有合法窗口)、t≤0(不符合问题定义),直接返回空集合。
- 计数优化:用
collections.defaultdict统计子串次数,比普通dict更省心,不用提前判断键是否存在;当某个子串计数减到0时直接删除键,避免字典积累无效数据。 - 滑动效率:每次滑动仅需两次操作(移除旧子串、添加新子串),整体时间复杂度为O(n)(n是字符串s的长度),属于最优的线性时间复杂度。
- 去重处理:用集合
clumps存储结果,自动避免同一个子串被多次添加(比如它可能在多个窗口里都满足条件,但我们只需要记录一次)。
示例验证
举个实际例子测试:
s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT" L = 10 t = 2 k = 2 print(find_clumps(s, L, t, k)) # 输出: {'AA', 'CC', 'CA'}
这个例子里,"AA"在多个长度为10的区间里出现≥2次,"CC"和"CA"同理,都被正确收集到结果里。
内容的提问来源于stack exchange,提问作者Sam Coutteau
相关产品推荐
相关产品推荐

