leetcode字符串的排列(滑动窗口)
问题描述:
给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。换句话说,s1 的排列之一是 s2 的 子串 。
示例:
输入:s1 = “ab” s2 = “eidbaooo”
输出:true
解释:s2 包含 s1 的排列之一 (“ba”).
代码:
class Solution {
public boolean checkInclusion(String s1, String s2) {
int n = s1.length(),m = s2.length();
if(n > m){
return false;
}
int[] cnt1 = new int[26];
int[] cnt2 = new int[26];
// 先统计前n个字符的词频(短字符串的长度)
for(int i = 0;i < n;i++){
cnt1[s1.charAt(i)-'a']++;
cnt2[s2.charAt(i)-'a']++;
}
// 判断是否相等
if(Arrays.equals(cnt1,cnt2)){
return true;
}
// 固定长度的滑动窗口向前滑动
for(int i=n;i<m;i++){
// 右边界向前滑一步(添加)
cnt2[s2.charAt(i)-'a']++;
// 左边界向前滑一步(去除)
cnt2[s2.charAt(i-n)-'a']--;
if(Arrays.equals(cnt1,cnt2)) return true;
}
return false;
}
}
解题思路:
因为排列是指这个字符串的每个字母顺序的改变,所以可以通过比较字母的词频来判断s2是否包含s1的排列之一。注意:这里的词频是只统计s1字符串长度大小的这样一段字符串的词频,所以可以通过一个定长的滑动窗口来解决。