找到字符串中所有字母异位词
题目:找到字符串中所有字母异位词
给定两个字符串s和p,找到s中所有p的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
# 思路一:循环字符串
循环遍历字符串s并截取相应p长度字符串进行对比。正常遍历提交时无法通过测试,这里做了下面几个个优化:
- 字符串对比使用先排序后转字符串再进行对比:
str.split('').sort().join('') - 借助额外对象空间缓存以存在的字符串避免重复进行字符串对比
- 判断新加入的字符
c.length-1是否在p中,不再则
var findAnagrams = function (s, p) {
let res = [], exist = {[p]: 1}
let pSort = p.split('').sort().join('')
exist[pSort] = 1
for (let i = 0; i <= s.length - p.length; i++) {
let c = s.slice(i, i + p.length)
if (exist.hasOwnProperty(c)) {
res.push(i)
} else {
if (!p.includes(c[c.length - 1])) {
i = i + p.length - 1
} else {
if (exist.hasOwnProperty(c)) {
res.push(i)
} else {
const cSort = c.split('').sort().join('')
if (cSort == pSort) {
exist[cSort] = 1
exist[c] = 1
res.push(i)
}
}
}
}
}
return res
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

通过优化遍历后可通过测试,但时间消耗有点大,所以下面使用官方提供的另一种思路进行求解
# 思路二:窗口法
根据题目要求,我们需要在字符串 s 寻找字符串 p 的异位词。因为字符串 p 的异位词的长度一定与字符串 p 的长度相同,所以我们可以在字符串 s 中构造一个长度为与字符串 p 的长度相同的滑动窗口,并在滑动中维护窗口中每种字母的数量;当窗口中每种字母的数量与字符串 p 中每种字母的数量相同时,则说明当前窗口为字符串 p 的异位词。
更多说明见:官方文档 窗口法
var findAnagrams = function (s, p) {
let res = []
let pWin = {}, sWin = {}, i = 0
for(let i = 0; i < p.length; i++) {
pWin[p[i]] = (pWin[p[i]] || 0) + 1
sWin[s[i]] = (sWin[s[i]] || 0) + 1
}
while(i <= s.length - p.length) {
let has = true
for(let key in pWin) {
if (pWin[key] != sWin[key]) {
has = false
break
}
}
has && res.push(i)
i ++
sWin[s[i - 1]] = sWin[s[i - 1]] - 1
if (sWin[s[i - 1]] == 0) {
delete sWin[s[i - 1]]
}
sWin[s[i + p.length - 1]] = (sWin[s[i + p.length - 1]] || 0) + 1
}
return res
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

上次更新: 2025/09/05, 8:09:00