题目
https://leetcode-cn.com/problems/permutation-in-string/
滑动窗口
窗口的大小为字符串1的长度,由于要找到字符串2中是否包含字符串1的排列所以只要字符串2的窗口中的字符出现频次等于字符串1中的字符出现频次就说明找到了一个排列,每次移动窗口只需要维护新加入窗口元素的频次和离开窗口元素的频次。窗口每移动一次进行一次匹配
class Solution {
public boolean checkInclusion(String s1, String s2) {
int m = s1.length();
int n = s2.length();
if (m > n) {
return false;
}
int[] cnt1 = new int[26];
int[] cnt2 = new int[26];
for (int i = 0; i < m; i++) {
cnt1[s1.charAt(i) - 'a']++;
cnt2[s2.charAt(i) - 'a']++;
}
if (Arrays.equals(cnt1, cnt2))
return true;
for (int i = m; i < n; i++) {
cnt2[s2.charAt(i - m) - 'a']--;
cnt2[s2.charAt(i) - 'a']++;
if (Arrays.equals(cnt1, cnt2))
return true;
}
return false;
}
}
优化:
可以不维护元素的频次进行匹配
class Solution {
public boolean checkInclusion(String s1, String s2) {
int m = s1.length();
int n = s2.length();
if (m > n) {
return false;
}
int[] cnt = new int[26];
for (int i = 0; i < m; i++) {
cnt[s1.charAt(i) - 'a']--;
}
int left = 0;
int right = 0;
while (right < n) {
cnt[s2.charAt(right) - 'a']++;
while (cnt[s2.charAt(right) - 'a'] > 0) {
cnt[s2.charAt(left) - 'a']--;
left++;
}
if (right - left + 1 == m)
return true;
right++;
}
return false;
}
}