567. 字符串的排列

120 阅读2分钟

567. 字符串的排列

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

题目描述

给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。

换句话说,s1 的排列之一是 s2 的 子串 。

示例 1:

输入: s1 = "ab" s2 = "eidbaooo"
输出: true
解释: s2 包含 s1 的排列之一 ("ba").

具体题目链接: 题目链接

思路:

思路:滑动窗口思路

窗口扩展时寻找可行解,窗口收缩时优化可行解

当滑动窗口可以定长时,一直维护k个长度的滑动窗口即可

当滑动窗口需要不定长时,需要通过特定条件(比如滑动窗口的总和)来判断left和right指针 到底是移动哪个

分析:

最小覆盖子串的简单版本 如果只需要关注总数/次数,就可以用nums数组来维护状态,而不需要hash 这里给出其他的解法

保持只有一个滑动窗口,s1和s2的长度 如果相等就退出

代码:

var checkInclusion = function(s1, s2) {
    let n = s1.length;//子串
    let m = s2.length;//全串

    if(n>m) return false;

    let res1 = new Array(26).fill(0);
    let res2 = new Array(26).fill(0);

    for(let i=0;i<n;i++) {//统计数据
        res1[s1[i].charCodeAt()-'a'.charCodeAt()]++;
        res2[s2[i].charCodeAt()-'a'.charCodeAt()]++;
    }

    if(res1.toString() == res2.toString()){//如果一开始就相等
        return true;
    }
    let i=n;
    while(i<m) {//滑动窗口
        res2[s2[i].charCodeAt()-'a'.charCodeAt()]++;
        res2[s2[i-n].charCodeAt()-'a'.charCodeAt()]--;// 保持只有一个滑动窗口,s1和s2的长度一样
        if(res1.toString() == res2.toString()){//如果相等就退出
            return true;
        }
        i++;
    }
    return false;
};

总结:

这是算法系列文章「滑动窗口」的相关题解

类型滑动窗口类型题目,解题方法窗口扩展时寻找可行解,窗口收缩时优化可行解