目录
- 题目截图
- 题目分析
- ac code
- 总结
题目截图
题目分析
- 简单的子序列判断需要on,那么最后最坏就是omn,25 * 10 ^ 7爆炸
- 因此需要优化子序列判断
- 注意到此时的大字符串是同一个
- 记录每个字母出现的下标
- 遍历word,找到下一个最近的字母出现的位置(使用该字母的下标list + 二分)
- 注意p = -1开始,使用bisect_right代表是寻找下一个
- 如果在这个字母的下标list ps中,已经去到len(ps) 说明找不到合适的下一个位置
- 直接返回False
- 复杂度优化为sum(sizei * logn) m个sum
ac code
class Solution:
def numMatchingSubseq(self, s: str, words: List[str]) -> int:
ans = 0
# 判断s是否是t的子序列,二分优化
# 假设t是固定的
pos = defaultdict(list)
for i, c in enumerate(s):
pos[c].append(i)
def isSubsequence(s, t):
# 二分优化
n, m = len(s), len(t)
if not s:
return True
if n > m:
return False
p = -1
for ch in s:
ps = pos[ch] # 这个字母对应的下标list
j = bisect_right(ps, p) # 下一个最近的ch的位置的ps中的下标
if j == len(ps): # 表示找不到了
return False
p = ps[j]
return True
for word in words:
if isSubsequence(word, s):
ans += 1
return ans
总结
- 对子序列模板在同一个大字符串下的优化
- 字母下标提取 + 二分快速定位下一个
- 字母下标一致,预处理即可