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 <= 104s1和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 :双指针中的 固定窗口的应用,可以很好地处理这类字符串的问题。注意将子串变成数组里面的计数方式来进行,会很好的处理。