给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。javascript
示例:java
输入: s1 = "ab" s2 = "eidbaooo"
输出: True
解释: s2 包含 s1 的排列之一 ("ba").
输入: s1= "ab" s2 = "eidboaoo"
输出: False
复制代码
输入的字符串只包含小写字母,两个字符串的长度都在 [1, 10,000] 之间。bash
遍历整个 s2,每次取固定长度的字符串,而后和 s1 进行比较.函数
这种解法的时间复杂度为 N 的三次方。leetcode上会提示超时。。显然不太可行测试
事先准备一个字典和初始的窗口,字典和窗口里都保存了对应字母出现的次数。而后开始遍历 s2,每次都比较一下字典和窗口里的字母对应出现次数一致不一致,若是不一致则将窗口第一个字母数量-1,将窗口下一个字母加进去。 这样至关于每一次遍历都向右平移了一下窗口,并且能够保留以前的大部分数据。ui
这种解法的时间复杂度为 N 的二次方。测试经过,开心。spa
具体解法以下:code
/** * @param {string} s1 * @param {string} s2 * @return {boolean} */
var checkInclusion = function(s1, s2) {
if(s1.length > s2.length){
return false
}
if(s1.length === 1){
return s2.includes(s1)
}
let book={},myBook={}
// 建立字典
for(let i=0;i<s1.length;i++){
book[s1.charAt(i)] ? book[s1.charAt(i)]++ : book[s1.charAt(i)] = 1
}
// 保存第一个窗口
for(let i=0;i<s1.length;i++){
myBook[s2.charAt(i)] ? myBook[s2.charAt(i)]++ : myBook[s2.charAt(i)] = 1
}
// 开始滑动窗口
for(let i=s1.length;i<=s2.length;i++){
if(check(book,myBook)){
return true
}else{
myBook[s2.charAt(i-s1.length)]--
myBook[s2.charAt(i)] ? myBook[s2.charAt(i)]++ : myBook[s2.charAt(i)] = 1
}
}
return false
// 比较字典和窗口
function check(book,myBook){
let keys = Object.keys(book)
for(let i=0;i<keys.length;i++){
if(book[keys[i]] !== myBook[keys[i]]){
return false
}
}
return true
}
};
复制代码