当前位置:网站首页>leetcode-438. 找到字符串中所有字母异位词(滑动窗口)
leetcode-438. 找到字符串中所有字母异位词(滑动窗口)
2022-07-31 05:10:00 【lin钟一】

题目链接:https://leetcode.cn/problems/find-all-anagrams-in-a-string/
思路
方法一:滑动窗口
直接想法
我们需要找到与p字符串的异位词,所以子串的长度与p字符串相同,我们可以用滑动窗口的方法,统计当前子串的字符数量是否可以跟p字符串匹配
算法
- 遍历数组,在滑动中统计窗口每种字符的数量
- 对比s的滑动窗口中的字符数量是否与p字符串中的字符数量相等
代码示例
func findAnagrams(s, p string) (ans []int) {
sLen, pLen := len(s), len(p)
if sLen < pLen{
return
}
var mps, mpt [26]int
for i := range p{
mps[s[i] - 'a']++
mpt[p[i] - 'a']++
}
if mps == mpt{
ans = append(ans, 0)
}
for i := range s[:sLen - pLen]{
//维护窗口中所有字符的数量
mps[s[i] - 'a']--
mps[s[i + pLen] - 'a']++
if mps == mpt{
ans = append(ans, i + 1)
}
}
return
}

复杂度分析
- 时间复杂度: O((n - m) * m) 其中n表示s字符串的长度,m表示p字符串的长度,因为一次滑动窗口对比字符数量的时间是O(m),总共滑动n - m次
- 空间复杂度:O(26 * 2) 总共开辟两个26长度的数组
方法二:优化滑动窗口
直接想法
在方法一的基础上,发现我们在每次滑动的时候都要对比字符数量是否相等,极大浪费时间,我们其实可以用一个变量记录每次滑动是改变的字符数量d
算法
- 在方法一的基础上,不用对比字符数量,用d记录滑动窗口中不同字符的数量
- 每次滑动的时候,用d记录是否跟上一次的字符数量不同
- d为0则表示是异位词,记录位置
代码示例
func findAnagrams(s, p string) (ans []int) {
sLen, pLen := len(s), len(p)
if sLen < pLen{
return
}
var mps [26]int
for i := range p{
mps[s[i] - 'a']++
mps[p[i] - 'a']--
}
//记录不同字符的数量
d := 0
for i := range mps{
if mps[i] != 0{
d++
}
}
if d == 0{
ans = append(ans, 0)
}
for i := range s[:sLen - pLen] {
//不同变相同
if mps[s[i] - 'a'] == 1{
d--
//相同变不同
}else if mps[s[i] - 'a'] == 0{
d++
}
mps[s[i] - 'a']--
//不同变相同
if mps[s[i + pLen] - 'a'] == -1{
d--
//相同变不同
}else if mps[s[i + pLen] - 'a'] == 0{
d++
}
mps[s[i + pLen] - 'a']++
if d == 0{
ans = append(ans, i + 1)
}
}
return
}

复杂度分析
- 时间复杂度: O(n) 其中n表示s字符串的长度,遍历p字符串需要O(m)的时间,遍历s字符串需要O(n - m)的时间,刚好加起来是O(n)的时间
- 空间复杂度:O(26) 总共开辟一个26长度的数组
边栏推荐
- 对递归的一些感悟
- uni-app进阶之生命周期【day8】
- [Introduction to MySQL 8 to Mastery] Basics - silent installation of MySQL on Linux system, cross-version upgrade
- mysql5.7.35安装配置教程【超级详细安装教程】
- 12 【网页布局总结 元素的显示与隐藏】
- docker安装postgresSQL和设置自定义数据目录
- Redis的初识
- 面试官,不要再问我三次握手和四次挥手
- 【JS面试题】面试官:“[1,2,3].map(parseInt)“ 输出结果是什么?答上来就算你通过面试
- 【数据库学习】Redis 解析器&&单线程&&模型
猜你喜欢

剑指offer基础版 ---- 第29天

面试官,不要再问我三次握手和四次挥手
uni-app进阶之模版语法与数据绑定【day7】

Anaconda配置环境指令

Distributed Transactions - Introduction to Distributed Transactions, Distributed Transaction Framework Seata (AT Mode, Tcc Mode, Tcc Vs AT), Distributed Transactions - MQ
uni-app进阶之认证【day12】

面试官竟然问我怎么分库分表?幸亏我总结了一套八股文

MySQL8.0.26安装配置教程(windows 64位)

05 【绑定样式 条件渲染 列表渲染】

C语言实验五 循环结构程序设计(二)
随机推荐
三次握手与四次挥手
The process and specific code of sending SMS verification code using flask framework
16 【打包上线 图片懒加载】
Flask 的初识
[Introduction to MySQL 8 to Mastery] Basics - silent installation of MySQL on Linux system, cross-version upgrade
解决响应式数据依赖响应式数据无响应问题
剑指offer基础版 --- 第24天
Distributed transaction processing solution big PK!
tf.keras.utils.get_file()
Object Detection Study Notes
Why use Flink and how to get started with Flink?
账号或密码多次输入错误,进行账号封禁
为什么要用Flink,怎么入门使用Flink?
MySQL8--Windows下使用压缩包安装的方法
详解扫雷游戏(C语言)
Anaconda配置环境指令
梳理一下自己常用的快捷键
uni-app进阶之创建组件/原生渲染【day9】
Redis Advanced - Cache Issues: Consistency, Penetration, Penetration, Avalanche, Pollution, etc.
剑指offer基础版 ----- 第25天