给定两个字符串 s 和 p,找到 s中所有 p的 异位词的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
示例 1:
输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
示例 2:
输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。
提示:
1 <= s.length, p.length <= 3 *s和p仅包含小写字母
解题思路:
- 若
s的长度小于p的长度,直接返回空列表(不可能存在异位词)。 - 分别统计
p的字符频率和s中长度为len(p)的初始窗口的字符频率。 - 滑动窗口遍历
s:每次窗口右移一位,更新窗口的字符频率,并比较当前窗口与p的字符频率是否一致。若一致,则记录当前窗口的起始索引。
Python代码:
python
from typing import List
import re
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
n, m = len(s), len(p)
if n < m:
return []
cnt_p = [0] * 26
cnt_s = [0] * 26
for i in range(m):
cnt_p[ord(p[i]) - ord('a')] += 1
cnt_s[ord(s[i]) - ord('a')] += 1
res = []
if cnt_p == cnt_s:
res.append(0)
for i in range(1, n - m + 1):
cnt_s[ord(s[i - 1]) - ord('a')] -= 1
cnt_s[ord(s[i + m - 1]) - ord('a')] += 1
if cnt_p == cnt_s:
res.append(i)
return res
if __name__ == "__main__":
# 处理输入(格式如:s = "cbaebabacd",p = "abc")
s_input = input().strip()
p_input = input().strip()
# 提取字符串内容
s = re.search(r'"(.*?)"', s_input).group(1)
p = re.search(r'"(.*?)"', p_input).group(1)
solution = Solution()
result = solution.findAnagrams(s, p)
print(result)
LeetCode提交代码:
python
class Solution:
from typing import List
def findAnagrams(self, s: str, p: str) -> List[int]:
n, m = len(s), len(p)
if n < m:
return []
# 初始化字符频率数组(仅小写字母,长度为26)
cnt_p = [0] * 26
cnt_s = [0] * 26
# 统计p的字符频率和s的初始窗口(前m个字符)的频率
for i in range(m):
cnt_p[ord(p[i]) - ord('a')] += 1
cnt_s[ord(s[i]) - ord('a')] += 1
res = []
# 检查初始窗口是否为异位词
if cnt_p == cnt_s:
res.append(0)
# 滑动窗口遍历剩余部分
for i in range(1, n - m + 1):
# 移除窗口左侧的字符
cnt_s[ord(s[i-1]) - ord('a')] -= 1
# 加入窗口右侧的新字符
cnt_s[ord(s[i + m - 1]) - ord('a')] += 1
# 检查当前窗口是否为异位词
if cnt_p == cnt_s:
res.append(i)
return res
程序运行结果如下:

总结
本文介绍了在字符串s中查找所有p的异位词子串的算法。异位词指字母相同但顺序不同的字符串。算法采用滑动窗口法,通过维护两个字符频率数组(分别对应p和s的当前窗口)进行比较。具体步骤包括:1)检查s长度不小于p;2)初始化字符频率数组;3)滑动窗口遍历s,更新窗口频率并比较。时间复杂度为O(n),空间复杂度为O(1)。示例输入如s="cbaebabacd",p="abc"时输出[0,6],验证了算法的正确性。该解法适用于处理小写字母组成的字符串匹配问题。