当前位置:网站首页>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长度的数组
边栏推荐
- Lock wait timeout exceeded解决方案
- leetcode-每日一题剑指 Offer II 041. 滑动窗口的平均值(队列模拟)
- 实验8 DNS解析
- 实验7 UDP与TCP对比
- Quickly master concurrent programming --- the basics
- 【mysql 提高查询效率】Mysql 数据库查询好慢问题解决
- If the account number or password is entered incorrectly for many times, the account will be banned.
- 剑指offer基础版 --- 第21天
- 【C语言3个基本结构详解——顺序、选择、循环】
- 太厉害了,终于有人能把文件上传漏洞讲的明明白白了
猜你喜欢
随机推荐
C语言文件读、写、定位函数
05 【绑定样式 条件渲染 列表渲染】
uni-app进阶之生命周期【day8】
快速掌握并发编程 --- 基础篇
剑指offer基础版--- 第23天
剑指offer基础版 ----- 第28天
【MQ我可以讲一个小时】
C语言的文件操作(一)
Qt Creator + CMake 运行调试总会自动 build 所有目标
Redis 事务学习有感
再见了繁琐的Excel,掌握数据分析处理技术就靠它了
The process and specific code of sending SMS verification code using flask framework
关于superset集成到自己的项目中
04 【计算属性 侦听属性】
C语言实验五 循环结构程序设计(二)
Simple command of mysql
C语言实验二 数据类型、运算符和表达式
C语言教程(三)-if和循环
Redis进阶 - 缓存问题:一致性、穿击、穿透、雪崩、污染等.
剑指offer专项突击版 ---- 第2天







