LC-567. 字符串的排列

167 阅读1分钟

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

题目描述

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

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

示例 1:

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

示例 2:

输入: s1= "ab" s2 = "eidboaoo"
输出: false

提示:

  • 1 <= s1.length, s2.length <= 104
  • s1 和 s2 仅包含小写字母

题解

1.固定窗口

这道题 由于是判断 s1 是否是 s2 的字串,且s1的长度是固定的,那么我们可以通过创建两个指针来组成固定窗口,下面是几个步骤点。

  • 如果s1的长度小于s2的长度的话,直接返回false。

  • 由题目可知,只有小写的英文字母,所以创建两个26个字符的数组并填充0

  • 进行第一次固定窗口的取值,之后进行判断两个数组的tostring()方法后,是否一致

  • 之后进行固定窗口的向右移动,每移动依次,就来进行判断 两个数组的tostring()方法后,是否一致,直到固定窗口的右指针的值等于s2的长度截止。

const checkInclusion = (s1, s2) => {
    const n = s1.length, m = s2.length;
    if (n > m) {
        return false;
    }
    const cnt1 = new Array(26).fill(0);
    const cnt2 = new Array(26).fill(0);
    for (let i = 0; i < n; ++i) {
        ++cnt1[s1[i].charCodeAt() - 'a'.charCodeAt()];
        ++cnt2[s2[i].charCodeAt() - 'a'.charCodeAt()];
    }
    if (cnt1.toString() === cnt2.toString()) {
        return true;
    }
    for (let i = n; i < m; ++i) {
        ++cnt2[s2[i].charCodeAt() - 'a'.charCodeAt()];
        --cnt2[s2[i - n].charCodeAt() - 'a'.charCodeAt()];
        if (cnt1.toString() === cnt2.toString()) {
            return true;
        }
    }
    return false;
};

总结

题目 8 :双指针中的 固定窗口的应用,可以很好地处理这类字符串的问题。注意将子串变成数组里面的计数方式来进行,会很好的处理。