给出一个 字符串 "abc",判断它是否是字符串 "adcba" 的异位词。
这题比较直观的解法是使用双指针来解答,先使用 map 记录 s1 每个字符的个数,然后遍历 s2,每次遍历开启双指针,start 为当前遍历索引,end 为 start + s1.length。这段区间的字符长度和 s1 一致,我们只需更新 map 列表,双指针执行结束时,如果 map 全是 0,那么是 s2 的子字符串是 s1 的异位词。
下面解法和上面解法有着异曲同工之妙。
// map 全为 0
function everyZero(map){
return Object.values(map).every(i => i===0)
}
function solve(s1, s2) {
if(typeof s1 !== 'string' || typeof s2 !== 'string') return false
if(s1.length > s2.length) return false
const map = {};
// 迭代 s1,以字符为 key 存在字符个数
s1.split('').map((i, index)=>{
if(!map[i]) map[i] = 0
map[i]++
// 遇到 s2 的字符,则减
if(!map[s2[index]]) map[s2[index]] = 0
map[s2[index]]--
})
// 判断是否开头存在变位
const bool = everyZero(map)
if(bool) return bool
let len = s1.length;
// 迭代 s2, 新的字符则 -, 旧的字符则加
// 因为之前减了,所以后面加上,如果存在异位,则 map 全为 0
for(let i = len; i < s2.length; i++){
let val = s2[i];
if(!map[val]) map[val] = 0
map[val]--
map[s2[i - len]]++
const bool = everyZero(map)
if(bool) return bool
}
return false
}