【LeetCode刷题】NO.8

123 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一.题目

438. 找到字符串中所有字母异位词 给定两个字符串 s 和 p,找到 s 中所有 p异位词的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。 示例 1:

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

示例 2:

输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。

提示:

  • 1 <= s.length, p.length <= 3 * 104
  • s 和 p 仅包含小写字母

二、思路分析:

看题目中说的时寻找字符串中的字母异位词,但是实际上还是寻找字符串中跟目标串所有排列中相等的子串问题,对于这种子串问题,还是利用滑动窗口的思想进行求解,求解的思路跟我上一篇文章几乎没有什么差别。

这个题目主要求出目标串的异位词,我们就可以利用这个点对框架进行优化,将window滑动窗口对象转变为Map数据结构更为合适,首先如果移入的字符在目标串当中,那么Map数据结构直接使用clear方法将存储的数组全部清空,如何right-left的长度没有跟目标串的长度相等也不用考虑,相等的话直接进入判断符合的字符数值valid是否与目标串的字符数值相等,相等则直接向结果result推入left数值,在进行滑动窗口操作再继续循环直到右指针到达字符串s的最右端。

三、代码:

/**
 * @param {string} s
 * @param {string} p
 * @return {number[]}
 */
var findAnagrams = function(s, p) {
    //分别计算字符串长度
    let slen = s.length;
    let plen = p.length;
    //定义滑动窗口以及符合数
    let left = 0,right = 0,valid = 0;
    let result = [];
    //统计目标字符串的个数
    const objectS = new Map();
    for(let i=0;i<plen;i++){
        objectS.set(p[i],objectS.has(p[i])?objectS.get(p[i])+1:1);
    }
    //统计滑动窗口的值
    const window = new Map();
    while(right<slen){
        let c = s[right];
        right++;
        //进入窗口的是所需的字符就加入
        if(objectS.has(c)){
            window.set(c,window.has(c)?window.get(c)+1:1);
            if(window.get(c) == objectS.get(c)) valid++;
        }else{
            left=right;
            valid = 0;
            window.clear();
            continue;
        }
        if(right-left == plen){
            if(valid == objectS.size){
                result.push(left);
            }
            //进行滑动窗口操作
            let x = s[left];
            left++;
            if(objectS.has(x)){
                if(window.get(x) == objectS.get(x)) valid--;
                window.set(x,window.get(x)-1);
            }
        }
    }
    return result;
};

四、总结:

这是字符串问题的第三题,利用滑动窗口的框架做题思路还是非常清晰的,针对特定的结果只需要优化一部分代码就可以了,如果熟练掌握滑动窗口思想遇到这类问题往往能够举一反三!根据labuladong大佬的思路进行算法的求解果然很得心应手0.0