当前位置:网站首页>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长度的数组
边栏推荐
- leetcode-每日一题剑指 Offer II 041. 滑动窗口的平均值(队列模拟)
- C语言文件读、写、定位函数
- 07 【内置指令 自定义指令】
- C语言实验三 选择结构程序设计
- 分布式事务处理方案大 PK!
- 【C语言3个基本结构详解——顺序、选择、循环】
- C语言如何分辨大小端
- 关于小白安装nodejs遇到的问题(npm WARN config global `--global`, `--local` are deprecated. Use `--location=glob)
- The TOKEN value of Kubernetes joining the cluster expires
- 闭包(四)----IIFE
猜你喜欢

Interviewer, don't ask me to shake hands three times and wave four times again

leetcode-每日一题731. 我的日程安排表 II

With MVC, why DDD?

04 【计算属性 侦听属性】

The interviewer asked me how to divide the database and the table?Fortunately, I summed up a set of eight-part essays

leetcode-每日一题剑指 Offer II 041. 滑动窗口的平均值(队列模拟)

剑指offer专项突击版 ---- 第2天

太厉害了,终于有人能把文件上传漏洞讲的明明白白了

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

Redis管道技术/分区
随机推荐
闭包(四)----IIFE
面试官问我TCP三次握手和四次挥手,我真的是
C语言指针详解
Interviewer: If the order is not paid within 30 minutes, it will be automatically canceled. How to do this?
【数据库学习】Redis 解析器&&单线程&&模型
leetcode-每日一题558. 四叉树交集(分治递归)
numpy和pytorch中的元素拼接操作:stack,concatenat,cat
C语言实验五 循环结构程序设计(二)
剑指offer专项突击版 ---- 第 6 天
The interviewer asked me how to divide the database and the table?Fortunately, I summed up a set of eight-part essays
Flink sink redis writes to Redis
Why use Flink and how to get started with Flink?
[MQ I can speak for an hour]
Proteus 8 Professional安装教程
Flask 的初识
剑指offer基础版 ---- 第29天
数据库上机实验4 数据更新和视图
leetcode-每日一题565. 数组嵌套(标记图和并查集)
关于小白安装nodejs遇到的问题(npm WARN config global `--global`, `--local` are deprecated. Use `--location=glob)
面试Redis 高可靠性|主从模式、哨兵模式、Cluster集群模式