【LeetCode刷题】找到字符串中所有字母异位词

给定两个字符串 sp,找到 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 *
  • sp 仅包含小写字母

解题思路:

  1. s 的长度小于 p 的长度,直接返回空列表(不可能存在异位词)。
  2. 分别统计 p 的字符频率和 s 中长度为 len(p) 的初始窗口的字符频率。
  3. 滑动窗口遍历 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,验证了算法的正确性。该解法适用于处理小写字母组成的字符串匹配问题。

相关推荐
Patrick在香港2 分钟前
模型路由器实测:12 个任务省 77%,旗舰过载时的降级要打出显式标记
python·llm·智能路由器·api·架构设计·成本优化
Looooking11 分钟前
Python 之 jwt 令牌生成和校验
python·jwt
明月_清风34 分钟前
从二叉树到 B+ 树:一文搞懂工程中「树」的演化之道
数据结构·算法·go
渡我白衣38 分钟前
并查集:基础认识与模拟实现
android·java·javascript·数据结构·c++·算法·并查集
hetao17338371 小时前
2026-09-01~09-04 hetao1733837 的刷题记录
c++·算法
Evand J1 小时前
【MATLAB例程,图像滤波5】 反谐波均值滑动窗口滤波(CHMF)图像降噪与质量评价,附代码下载链接
图像处理·算法·计算机视觉·matlab·均值算法·滑动窗口滤波·均值滑动
2601_962295991 小时前
嵌入式开发语言用哪个最好,C,python或者其他
c语言·python·嵌入式开发·开发效率·系统资源
菜鸡66662 小时前
绕过cf验证,部署 FlareSolverr 服务使用request处理
python·cloudflare
血小板要健康2 小时前
链表 阶段算法总结
java·数据结构·笔记·算法·leetcode·链表
a187927218312 小时前
【算法】回溯算法(三):三记重锤与 N 皇后——记忆化、状态设计与三层漏斗
算法·leetcode·go·剪枝·回溯·n皇后·算法讲解