Leetcode 438. 找到字符串中所有字母异位词

75 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情

1.题目

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。

示例 1:

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

2.思路

本题需要我们在字符串s中找到p的异位词,也就是我们需要找到和字符串p用词数量相同的字符串。那么我们只需要在字符串s中找到与字符串p长度相同的相邻字符串,然后判断字符串里面的字母数量是否与字符串p的用词数量相等,相等则说明是异位词,如果不相等则判断下一个字符串。

这也就是滑动窗口的思想,我们设定一个长度为字符串p的滑动窗口,然后判断窗口内的字符串数量是否满足用词数量,如果不满足则整体下移一位继续判断,在遍历时碰见满足的则收集窗口的开始位置,直到窗口的边缘碰到字符串末尾,最后再返回收集结果数组。

3.代码

var findAnagrams = function(s, p) {
    if(s.length<p.length){return []}
    let obj = {}
    let res = []
    p.split('').forEach(item=>{
        if(obj[item]){
            obj[item]=obj[item]+1
        }else{
            obj[item]=1
        }
    })
    let start = 0
    let end = p.length
    while(end<=s.length){
        let str = s.slice(start,end)
        let obj1 = {...obj}
        for(let i = 0;i<str.length;i++){
            if(obj1[str[i]]){
                obj1[str[i]]=obj1[str[i]]-1
            }
        }
        
        let result = true
        for(let i in obj1){
            if(obj1[i]!==0){
                result = false
            }
        }
        if(result){
            res.push(start)
        }
        start+=1
        end+=1
    }
    return res
};