567. 字串的排列
給你兩個字串s1
和s2
,寫乙個函式來判斷s2
是否包含s1
的排列。如果是,返回true
;否則,返回false
。
換句話說,s1
的排列之一是s2
的子串。
示例 1:
輸入:s1 = "ab" s2 = "eidbaooo"
輸出:true
解釋:s2 包含 s1 的排列之一 ("ba").
示例 2:
輸入:s1= "ab" s2 = "eidboaoo"
輸出:false
滑動視窗的思想:
用i
,j
表示滑動視窗的左邊界和右邊界,通過改變i
,j
來擴充套件和收縮滑動視窗,可以想象成乙個視窗在字串上游走,當這個視窗包含的元素滿足條件,即包含字串t的所有元素,記錄下這個滑動視窗的長度j-i+1
,這些長度中的最小值就是要求的結果。
步驟一不斷增加j
使滑動視窗增大,直到視窗包含了t的所有元素
步驟二不斷增加i
使滑動視窗縮小,因為是要求最小字串,所以將不必要的元素排除在外,使長度減小,直到碰到乙個必須包含的元素,這個時候不能再扔了,再扔就不滿足條件了,記錄此時滑動視窗的長度,並儲存最小值
步驟三讓i
再增加乙個位置,這個時候滑動視窗肯定不滿足條件了,那麼繼續從步驟一開始執行,尋找新的滿足條件的滑動視窗,如此反覆,直到j
超出了字串s範圍。
如何判斷滑動視窗包含了t的所有元素?
對於如何判斷滑動視窗中包含所有元素,我們可以使用乙個整數陣列,類似於以前做過的字串所有相同的字母異位詞問題和字母異位詞分組問題。
這裡可以優化的乙個地方就是,如果單純使用cnts陣列計數每個字元出現的次數,那麼在判斷的時候每次都需要判斷陣列中所有元素的數量都小於等於0時,表示當前滑動視窗不再需要任何元素。
具體地,我們可以再使用乙個計數指標cnt表示目標串中總共需要計數的字元數,並在滑動視窗的過程中維護該變數。最後,只需要判斷cnt是否為0即可。
本題與【最小覆蓋子串】問題的區別就是,本題中要求子串的排列出現在原串中,而不是子串。排列是有要求的,即字母順序可以不一樣,但是子串必須是連續的。這裡可以通過right-left+1是否等於n來判斷符合條件的子串是否連續。
class solution
while(right < m)
cnts[ch - 'a']--;
if(cnt == 0)
if(right - left + 1 == n)
}right++;
}return false;
}}
LeetCode 567 字串的排列
給定兩個字串 s1 和 s2,寫乙個函式來判斷 s2 是否包含 s1 的排列。換句話說,第乙個字串的排列之一是第二個字串的子串。示例1 輸入 s1 ab s2 eidbaooo 輸出 true 解釋 s2 包含 s1 的排列之一 ba 示例2 輸入 s1 ab s2 eidboaoo 輸出 fals...
leetcode 567 字串的排列
給定兩個字串 s1 和 s2,寫乙個函式來判斷 s2 是否包含 s1 的排列。換句話說,第乙個字串的排列之一是第二個字串的子串。示例1 輸入 s1 ab s2 eidbaooo 輸出 true 解釋 s2 包含 s1 的排列之一 ba 示例2 輸入 s1 ab s2 eidboaoo 輸出 fals...
LeetCode 567 字串的排列
給定兩個字串 s1 和 s2,寫乙個函式來判斷 s2 是否包含 s1 的排列。換句話說,第乙個字串的排列之一是第二個字串的子串。示例1 輸入 s1 ab s2 eidbaooo 輸出 true 解釋 s2 包含 s1 的排列之一 ba 示例2 輸入 s1 ab s2 eidboaoo 輸出 fals...