Leetcode 567 字符串的排列
题目定义:
给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。
换句话说,第一个字符串的排列之一是第二个字符串的子串。
示例1:
输入: s1 = "ab" s2 = "eidbaooo"
输出: True
解释: s2 包含 s1 的排列之一 ("ba").
示例2:
输入: s1= "ab" s2 = "eidboaoo"
输出: False
滑动窗口:
class Solution {
public boolean checkInclusion(String s1, String s2) {
int len1 = s1.length(),len2 = s2.length();
if(len1 > len2)
return false;
int[] cnt1 = new int[26];
int[] cnt2 = new int[26];
for(int i = 0;i < len1; i++){
cnt1[s1.charAt(i) -'a']++;
cnt2[s2.charAt(i) -'a']++;
}
if(Arrays.equals(cnt1,cnt2))
return true;
for(int i = len1; i < len2; i++){
cnt2[s2.charAt(i)-'a']++;
cnt2[s2.charAt(i - len1) -'a']--;
if(Arrays.equals(cnt1,cnt2))
return true;
}
return false;
}
}
优化版滑动窗口:
/*
* 思路:
* 注意到每次进行窗口滑动时,只统计了一进一出两个字符,但却比较了整个cnt1和cnt2 数组
* 我们可以用一个变量 diff 来记录cnt1 与 cnt2 的不同值的个数,这样判断cnt1 和cnt2 是否相等就转换成了判断diff是否为0
* 每次窗口滑动,记一进一出两个字符 x 和 y
* 若x == y 则对cnt2 无影响,直接跳过
* 若 x != y ,对于字符x,在修改cnt2之前若有 cnt2[x] == cnt1[x],则将diff++,在修改cnt2之后若有 cnt2[x] == cnt1[x] 则将diff-- 字符y 同理
* 此外,为简化上述逻辑,我们可以只用一个数组 cnt ,其中cnt[x] = cnt2[x] - cnt1[x],将cnt1[x] 与cnt2[x]的比较替换成cnt[x] 与0 的比较
*/
class Solution {
public boolean checkInclusion(String s1, String s2) {
int len1 = s1.length(),len2 = s2.length();
if(len1 > len2)
return false;
int[] cnt = new int[26];
int diff = 0;
for(int i = 0;i < len1; i++){
--cnt[s1.charAt(i) - 'a'];
++cnt[s2.charAt(i) - 'a'];
}
for(int i : cnt){
if(i != 0)
diff ++;
}
if(diff == 0)
return true;
for(int i = len1; i < len2; i++){
int x = s2.charAt(i) - 'a',y = s2.charAt(i - len1) - 'a';
if(x == y)
continue;
if(cnt[x] == 0)
diff++;
cnt[x]++;
if(cnt[x] == 0)
diff--;
if(cnt[y] == 0)
diff ++;
cnt[y]--;
if(cnt[y] == 0)
diff--;
if(diff == 0)
return true;
}
return false;
}
}
双指针:
class Solution {
public boolean checkInclusion(String s1, String s2) {
int n = s1.length(),m = s2.length();
if(n > m)
return false;
int[] cnt =new int[26];
for(int i = 0; i < n; i++){
cnt[s1.charAt(i) -'a']--;
}
int left = 0;
for(int right = 0; right < m; right++){
int x = s2.charAt(right) -'a';
++cnt[x];
while(cnt[x] > 0){
--cnt[s2.charAt(left) - 'a'];
++left;
}
if(right - left + 1 == n)
return true;
}
return false;
}
}
参考:
https://leetcode-cn.com/problems/unique-binary-search-trees/