給定兩個字符串 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
}
};
複製代碼