天天看點

LeetCode567,字元串的排列,滑動視窗,char轉換成int的方法寫這個學習筆記的原因是因為刷到LeetCode上這一題時發現有一個很巧妙的解法。

寫這個學習筆記的原因是因為刷到LeetCode上這一題時發現有一個很巧妙的解法。

首先看一下題目:

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

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

示例 1:

輸入: s1 = "ab" s2 = "eidbaooo"

輸出: True

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

示例 2:

輸入: s1= "ab" s2 = "eidboaoo"

輸出: False

解法大緻思路:

如果s2包含s1的排列,就說明s2中有一段與s1一樣長的子字元串中包含的每個字元的個數與s1包含的一樣。

設n為s1的長度

  • 維持一個固定長度為n的滑動視窗
  • 在s2上滑動視窗,同時統計視窗内的每個字元的個數
  • 每次往右滑動時,将原本視窗内的首字母移除一個,将右移後加進來的字母添加一個
  • 每次滑動後,統計視窗内每個字元的個數是否與s1相同

這裡有一個很巧妙的方法。就是在統計每個字元的個數時,可以用 char - ‘a'的方式把此char轉換成int。例如‘a'-’a' = 0, ‘b'-’a' = 1 。。。用此方法就可以用一個數組來統計每個字元的個數,比如,“ABC”就會變成【1,1,1】, “ABB”就會變成【1,2】。

拿題目的例子來說:

s1 = "ab" s2 = "eidbaooo"

s1Arr = 【1,1】

然後在s2上維持一個長度為2的移動視窗, 每次移動時更新視窗所對應的數組,然後比較數組是否相等。如相等則代表此時視窗内的字字元串是s1的排列

以下是代碼,參考 https://leetcode-cn.com/problems/permutation-in-string/solution/zi-fu-chuan-de-pai-lie-by-leetcode-solut-7k7u/

public static boolean checkInclusion2(String s1, String s2) {
        char[] s1Chars = s1.toCharArray();
        char[] s2Chars = s2.toCharArray();
        int[] s1Arr = new int[26];
        int[] temp = new int[26];

        for (int i = 0; i < s1.length(); i++) {
            s1Arr[s1Chars[i] - 'a']++;
            temp[s2Chars[i] - 'a']++;
        }
        if (Arrays.equals(temp, s1Arr)) {
            return true;
        }

        for (int i = s1.length(); i < s2.length(); i++) {
            temp[s2Chars[i] - 'a']++;
            temp[s2Chars[i - s1.length()] - 'a']--;
            if (Arrays.equals(temp, s1Arr)) {
                return true;
            }
        }
        return false;
    }
           

本人小白,寫的不好請指教!!