1、前言
题目描述2、思路
此题使用滑动窗口的思路来做。滑动窗口简而言之就是开始的时候定义一个窗口,然后不断的往右边滑动,直到滑动到尽头为止。那么怎么定义这个窗口呢?因为题目要求 s2 能否包含 s1,所以应该定义一个长度为 s1 长度的窗口,在 s2 上滑动。
假设 s1 长度为 m,初始时窗口现在 s2 上塞满 m 个字符,然后判断是否与 s1 的字符相同且频数一致,如果一致直接返回 true。然后接着在 s2 上滑动,直到滑动 s2 尽头。
有一点需要注意的是,对于频数为0的字符需要及时移除掉,因为 HashMap 的 equals 会比较 key 和 value。
3、代码
class Solution {
public boolean checkInclusion(String s1, String s2) {
Map<Character, Integer> window = new HashMap<>();
Map<Character, Integer> need = new HashMap<>();
int m = s1.length(), n = s2.length();
if(m > n) return false;
for (char c : s1.toCharArray()) {
need.put(c, need.getOrDefault(c, 0) + 1);
}
for(int i = 0; i < m; i++){
window.put(s2.charAt(i), window.getOrDefault(s2.charAt(i), 0) + 1);
}
if(window.equals(need)){
return true;
}
for(int i = m; i < n; i++){
char removeChar = s2.charAt(i - m);
char addChar = s2.charAt(i);
window.put(removeChar, window.get(removeChar) - 1);
if(window.get(removeChar) == 0){
window.remove(removeChar);
}
window.put(addChar, window.getOrDefault(addChar, 0) + 1);
if(window.equals(need)){
return true;
}
}
return false;
}
}
网友评论