滑动窗口了解
滑动窗口问题经常用于解决连续字串问题,设置left和right指针不断滑动,找到最后需要的结果
难点:左指针移动条件需要清晰明确
滑动窗口通用模板如下
int left = 0, right = 0;
int flag = 0; //用于确定是否将所需字串全部包括
Map<Character, Integer> targe, current;
targe = new HashMap<>();
current = new HashMap<>();
List<Integer> result = new ArrayList<>();
//将子串p存放在targe集合中
for(Character c : p.toCharArray()) targe.put(c, targe.getOrDefault(c, 0) + 1);
while(right < s.length()) {
char c = s.charAt(right);
right++;
...
//判断left是否要移动
while (right - left >= p.length()) {
....
}
}
滑动窗口的题目套用上面这个模板即可
题解:
看这个题,就是找连续字串的变形问题,只是多一步将满足字串的起始索引放入List集合中
所以套用公式
class Solution {
public List<Integer> findAnagrams(String s, String p) {
int left = 0, right = 0;
int flag = 0;
Map<Character, Integer> targe, current;
targe = new HashMap<>();
current = new HashMap<>();
List<Integer> result = new ArrayList<>();
for(Character c : p.toCharArray()) targe.put(c, targe.getOrDefault(c, 0) + 1);
while(right < s.length()) {
char c = s.charAt(right);
right++;
//判断c字符是否存在再目标字符串p中,存在就将current中c键对应的value值+1
if(targe.containsKey(c)) {
current.put(c, current.getOrDefault(c, 0) + 1);
//如果这个目标字符串和当前滑动中窗口的字符串value值一致,代表找到一个,将flag++
if(targe.get(c).equals(current.get(c))) {
flag++;
}
}
//这里看是否将窗口缩小
while (right - left >= p.length()) {
//如果当前窗口中已经包括全部的目标字符串,将当前左指针向右移动
if(flag == targe.size())
result.add(left);
c = s.charAt(left);
left++;
//确定目标是否还包括全部目标字符串
if(targe.containsKey(c)) {
if(targe.get(c).equals(current.get(c)))
//已经不包括了,将flag--
flag--;
//再将窗口中的当前字符的value值-1
current.put(c, current.get(c) - 1);
}
}
}
return result;
}
}
最终得到全部的起始索引,至此题目完成