LeetCode : 567. 字串的排列(Permutation in String)解答
阿新 • • 發佈:2018-12-26
567. 字串的排列
給定兩個字串 s1
和 s2
,寫一個函式來判斷 s2
是否包含 s1
的排列。
換句話說,第一個字串的排列之一是第二個字串的子串。
示例1:
輸入: s1 = “ab” s2 = “eidbaooo”
輸出: True
解釋: s2 包含 s1 的排列之一 (“ba”).
示例2:
輸入: s1= “ab” s2 = “eidboaoo”
輸出: False
注意:
- 輸入的字串只包含小寫字母
- 兩個字串的長度都在 [1, 10,000] 之間
一、分析
-
判斷是否包含
s1
擷取s2
中某長度和s1
字串長度相等的子串,判斷兩者每個字元的數量是否一致即可。 -
統計字元數量
由於字串只包含 26 個小寫字母,我們可以使用 計數排序 來統計,即建立一個長度為 26 的陣列,其下標0 ~ 25
對應a ~ z
的每個字母,其值為對應字母出現的次數。 -
判斷條件
先統計s1
的字元數量count1
,再依次統計s2
中與之長度相等的子串的字元數量count2
,比較兩者是否相同。
二、解答
根據分析,我們可以在 O(n) 的時間複雜度完成解答。
class Solution {
public static void main(String[] args) {
System.out.println(checkInclusion("ab", "eidbaooo"));
System.out.println(checkInclusion("ab", "eidboaoo"));
}
public static boolean checkInclusion(String s1, String s2) {
if (s1 == null || s2 == null || s1.length() > s2.length()) {
return false;
}
int[] count1 = new int[26]; // s1每個字元出現的次數
int[] count2 = new int[26]; // s2每個字元出現的次數
// 1. 進行統計
for (int i = 0; i < s1.length(); i++) {
count1[s1.charAt(i) - 'a']++;
count2[s2.charAt(i) - 'a']++;
}
// 2. 滑動視窗,滑塊長度始終為 s1.length()
for (int i = s1.length(); i < s2.length(); i++) {
if (isSame(count1, count2)) {
return true;
}
count2[s2.charAt(i - s1.length()) - 'a']--; // 去掉滑塊當前的首個字元
count2[s2.charAt(i) - 'a']++; // 新增最新的字元到滑塊中
}
return isSame(count1, count2);
}
// 有且僅當 count1 中所有值都等於 count2 中對應值時滿足條件
public static boolean isSame(int[] count1, int[] count2) {
for (int i = 0; i < count1.length; i++) {
if (count1[i] != count2[i]) {
return false;
}
}
return true;
}
}
三、專案地址
https://github.com/afei-cn/LeetCode/tree/master/567.%20Permutation%20in%20String