找到字符串中第一次连续出现任意顺序“abcd“的下标(双指针) 滑动窗口

双指针法模板

前置条件:

窗口固定是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;
    }
}

. - 力扣(LeetCode)长度最小的子数组

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 ;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值