1. 程式人生 > >LeetCode : 567. 字串的排列(Permutation in String)解答

LeetCode : 567. 字串的排列(Permutation in String)解答

567. 字串的排列

給定兩個字串 s1s2,寫一個函式來判斷 s2 是否包含 s1 的排列。

換句話說,第一個字串的排列之一是第二個字串的子串。

示例1:

輸入: s1 = “ab” s2 = “eidbaooo”

輸出: True

解釋: s2 包含 s1 的排列之一 (“ba”).

示例2:

輸入: s1= “ab” s2 = “eidboaoo”

輸出: False

注意:

  1. 輸入的字串只包含小寫字母
  2. 兩個字串的長度都在 [1, 10,000] 之間

一、分析

  1. 判斷是否包含 s1

    的排列的方法:
    擷取 s2 中某長度和 s1 字串長度相等的子串,判斷兩者每個字元的數量是否一致即可。

  2. 統計字元數量
    由於字串只包含 26 個小寫字母,我們可以使用 計數排序 來統計,即建立一個長度為 26 的陣列,其下標 0 ~ 25 對應 a ~ z 的每個字母,其值為對應字母出現的次數。

  3. 判斷條件
    先統計 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

四、原題地址

https://leetcode-cn.com/problems/permutation-in-string/