双指针法模板
前置条件:
窗口固定是4---------一旦窗口大于4,左指针移动
窗口固定元素是abcd任意顺序------HashMap<{a,b,c,d},出现次数>并且四个value都是1就是找到了一组正确答案!
注意维护count的
/**
* 使用滑动窗口找出任意排序的abc的下标位置!
*/
public static void main(String[] args) {
String s="abbaccdddkabcd";
HashMap<Character,Integer>window=new HashMap<>();
int size=4;
int count=0;//记录abcd个出现一次的次数
for(char c:"abcd".toCharArray()){
window.put(c,0);
}
int r=0,l=0;
while(r<s.length()){
//右指针负责拓展,不管有没有{abcd}
char r_temp=s.charAt(r);
if(window.containsKey(r_temp)){
//注意只记录abcd中的任何一个
window.put(r_temp, window.get(r_temp)+1);
if(window.get(r_temp)==1){
//说明只出现一次!记录下来!!
count++;
}
}
//r一直向右找寻不管有没有abcd,直到窗口的大小超出了size
while(r-l+1>size){
//移除的是窗口的left
char window_left=s.charAt(l);
if(window.containsKey(window_left)){
window.put(window_left,window.get(window_left)-1);
if(window.get(window_left)==0){
count--;//说明没有了--
}
}
l++;
}
if(count==size) System.out.println("find!"+l);
r++;
}
}
class Solution {
public int lengthOfLongestSubstring(String s) {
//一定要思考清楚左右边界的作用
//右边,移动,直到遇到重复的字符
//左边用来缩小窗口直到不包含重复字符
int max=0;
int left=0,right=0;
HashSet<Character> hs = new HashSet<>();
//右边,移动
for( ;right<s.length();right++){
char c=s.charAt(right);
//直到遇到重复的字符
while(hs.contains(c)){
//注意,这里是关键--》不是这个 hs.remove(c);
//而是这个移除left!!移动左指针并移除字符,直到没有重复字符
hs.remove(s.charAt(left));
left++;
}
hs.add(c);
max=Math.max(max, right - left +1 );
}
return max;
}
}
class Solution {
public int minSubArrayLen(int target, int[] nums) {
//可以自己想象一个滑动的模块,右边不断扩大疆土,直到里面的大小比target大
//left就像一个路探不断缩小,直到有无比target大的!
//右边在拓宽的时候,一旦遇到相同的时候,左边的作用就是缩小到没有重复!
int left=0,right=0;
int count=0;
int min= Integer.MAX_VALUE;;
for( ;right<nums.length;right++){
//获取当前字符
count+=nums[right];
while(count>=target){
//如果疆土过大了
//注意是找到满足 找到一个子数组,使其总和大于或等于给定的 target
min=Math.min(min,right-left+1);
count-=nums[left];
left++;
}
}
return min== Integer.MAX_VALUE ? 0 : min ;
}
}