当前位置: 首页 > news >正文

leetcode 438.找到字符串中所有字母异位词

目录

题目描述

示例1:

示例2:

提示:

解题思路

Collections库

介绍

滑动窗口法

概念

应用场景及特点:

思路

流程展示

代码

复杂度分析


题目描述

给定两个字符串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 * (10**4)
  • sp 仅包含小写字母

解题思路

Collections库

介绍

Python的collections库是一个内建模块,它提供了一系列特殊的容器数据类型,用于扩展Python的标准内建容器(如字典、列表、集合和元组)。这些特殊的容器类型提供了比通用数据类型更多的选择和更好的性能,非常适合在需要高效数据处理和复杂数据结构时使用。

  • 具体使用详情
  • 官方地址

滑动窗口法

概念

滑动窗口是一个在序列上移动的区间,通常由左右两个指针来界定这个区间的范围。通过移动指针来改变窗口的大小和位置,在窗口移动的过程中,根据问题的需求进行特定的计算和处理。

应用场景及特点

  1. 子数组 / 子串问题
  • 当需要在一个序列中找到满足特定条件的连续子数组或子串时,滑动窗口非常适用。例如,寻找和为特定值的连续子数组、含有特定字符的最长子串等。
  • 窗口的大小通常是动态变化的,根据问题的条件进行调整。
  1. 高效性
  • 相比于暴力枚举所有可能的子数组 / 子串,滑动窗口法通常能够在更短的时间内找到解。因为它利用了子数组 / 子串的连续性和窗口的滑动特性,避免了重复计算。
  1. 指针移动规则
  • 通常有两个指针,一个指向窗口的左端,一个指向窗口的右端。根据问题的具体要求,以特定的方式移动指针。
  • 例如,在寻找满足特定条件的最小子数组时,可能会先扩大窗口直到满足条件,然后再缩小窗口以找到最小的满足条件的窗口。

思路

这道题可以使用滑动窗口(Sliding Window)和哈希表的结合来解决。解题的关键是如何有效地在字符串 s 中找到与字符串 p 的异位词相同的子串。

  1. 异位词特征:两个字符串是异位词,那么它们每个字符的出现次数是相同的。因此,我们可以使用字符频率来判断一个子串是否是异位词。
  2. 滑动窗口:我们在字符串 s 上维护一个大小为 len(p) 的滑动窗口,记录窗口内的字符频率。当窗口的大小等于 p 的长度时,我们检查窗口内的字符频率是否和 p 的字符频率相同。如果相同,则说明当前窗口是 p 的一个异位词,我们记录下窗口的起始索引。
  3. 窗口滑动:每次窗口滑动时,我们更新窗口的字符频率,移出窗口左边的一个字符,并添加右边新进入窗口的字符。

流程展示

代码

class Solution:  def findAnagrams(self, s: str, p: str) -> List[int]:  res = []n, m = len(s), len(p)if n < m:return res# 初始化p的字符频率p_count = collections.Counter(p)# 初始化窗口的字符频率window = collections.Counter(s[:m-1])for i in range(m-1, n):# 增加新的字符到窗口window[s[i]] += 1# 如果窗口字符频率和p字符频率相同,记录起始索引if window == p_count:res.append(i - m + 1)# 移除左边的字符,保持窗口大小为mwindow[s[i - m + 1]] -= 1if window[s[i - m + 1]] == 0:del window[s[i - m + 1]]return res

复杂度分析

  • 时间复杂度O(n),其中 n 是字符串 s 的长度。遍历字符串 s 需要 O(n) 时间,在每次窗口移动时,我们对窗口内的字符进行更新和比较,哈希表的比较是 O(1),因此总时间复杂度是 O(n)
  • 空间复杂度O(m),其中 m 是字符串 p 的长度。我们使用了两个哈希表来存储字符频率,每个哈希表最多存储 m 个不同的字符,因此空间复杂度是 O(m)

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 突破编程:C++中的组合模式(Composite Pattern)
  • linux下搭建MySQL8.0.25一主一从
  • rust 日志记录与跟踪
  • 沉浸式解压小视频在哪找?非常减压的几个视频素材网站分享
  • NLP发展脉络-->特征优化阶段
  • SAM 2——视频和图像实时实例分割的全新开源模型
  • matlab实现粒子群优化算法
  • AI学习记录 - 怎么理解 torch 的 nn.Conv2d
  • Godot《躲避小兵》实战之创建游戏主场景
  • 怎么写spring security的账号密码成功失败处理器并且加一个验证码过滤器
  • 错误提示:‘interface‘ declarations can only be used in TypeScript files
  • 解读FastAPI异步化为transformers模型打造高性能接口解析
  • 【在Linux世界中追寻伟大的One Piece】应用层协议HTTP
  • 关于Java中@Component的使用中出现@Autowired为NULL的问题
  • 模型 FIRE沟通法
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 《Java编程思想》读书笔记-对象导论
  • 2018一半小结一波
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • Hibernate【inverse和cascade属性】知识要点
  • JavaScript创建对象的四种方式
  • Java的Interrupt与线程中断
  • Map集合、散列表、红黑树介绍
  • ReactNative开发常用的三方模块
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 计算机常识 - 收藏集 - 掘金
  • 扑朔迷离的属性和特性【彻底弄清】
  • 七牛云假注销小指南
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 三分钟教你同步 Visual Studio Code 设置
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 再谈express与koa的对比
  • 【云吞铺子】性能抖动剖析(二)
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • #职场发展#其他
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (6) 深入探索Python-Pandas库的核心数据结构:DataFrame全面解析
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (Windows环境)FFMPEG编译,包含编译x264以及x265
  • (第三期)书生大模型实战营——InternVL(冷笑话大师)部署微调实践
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (三)mysql_MYSQL(三)
  • (四)JPA - JQPL 实现增删改查
  • ***测试-HTTP方法
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .net core docker部署教程和细节问题
  • .net core 使用js,.net core 使用javascript,在.net core项目中怎么使用javascript
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .Net 执行Linux下多行shell命令方法
  • .NET程序集编辑器/调试器 dnSpy 使用介绍
  • .net和php怎么连接,php和apache之间如何连接