天天看点

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;
    }
           

本人小白,写的不好请指教!!