【滑动窗口】

滑动窗口应用场景

  • 满足一定条件
  • 最长、最短
  • 子序列/子串/子数组

简单介绍滑动窗口核心思想

找到最长连续红球子序列

在这里插入图片描述
(1)初始化窗口:左右指针初始化为-1;
(2)定义窗口的含义:如果right > left 只能容忍窗口中有红球
(3)移动右指针:此时窗口有1个红球则继续移动右指针
在这里插入图片描述
(4)窗口内出现白球,这是不容许的,因此移动left,使得left == right; 此时记下max = 1;
(5)继续滑动right;
(6)如此往复,知道right = arr.length

在这里插入图片描述

代码模板

在这里插入图片描述

实战

1.寻找最短

package 滑动窗口;

/**
 * https://leetcode-cn.com/problems/2VG8Kg/
 *
 * mid  99.95%
 */
public class 剑指Offer008_和大于等于target的最短子数组 {
    public int minSubArrayLen(int target, int[] nums) {

        if(nums[0] >= target) return 1;


        //定义窗口: 窗口内元素和 < target
        int left = 0;
        int right = 0;

        int sum = 0;
        int res = Integer.MAX_VALUE;

        while(right <  nums.length ){
            sum += nums[right];
            //todo 如果满足条件
            if(sum >= target){
                //移动左指针 到窗口不满足条件
                while(sum >= target){
                    sum -= nums[left++];
                }
                //更新最小值 
                //此时窗口不满足条件 right - left + 1 是窗口大小
                //left再往左边移动一个就满足了
                // 所以 窗口size + 1
                res = Math.min(right - left + 2,res);
            }
            right++;
        }

        //2 3 1 2
        //
        return res == Integer.MAX_VALUE? 0 : res;
    }


    public static void main(String[] args) {
        剑指Offer008_和大于等于target的最短子数组 v = new 剑指Offer008_和大于等于target的最短子数组();
        int[] nums = {1,1,1,1,1,1,1,1};
        int target = 11;

        System.out.println(v.minSubArrayLen(target,nums));
    }
}

2.寻找最长

package 滑动窗口;


import java.util.HashMap;
import java.util.HashSet;

/**
 * https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
 *
 * mid
 *
 * 69.8%
 */

public class No3_无重复字符的最长子串 {
    public int lengthOfLongestSubstring(String s) {
        if (s == null || s.length() == 0) return 0;
        //todo 1.定义窗口 [left,right] 没有重复元素
        int left = 0;
        int right = 0;

        int res = 1;
        //todo 2.定义map 存储窗口内的元素
        char[] chars = s.toCharArray();
        HashMap<Character,Integer> map = new HashMap<>();
        map.put(chars[0],0);

        while(right < s.length()-1){
            char element = chars[right+1];

            //如果窗口中包含
            //update res
            //窗口删除数据
            //移动左指针 和 右指针
            //窗口更新该元素索引
            if(map.containsKey(element)){
                Integer index = map.get(element);
                for(int i = left;i<= index;i++){
                    map.remove(chars[i]);
                }
                left = index + 1;
            }
            map.put(element,++right);
            res = Math.max(right - left + 1,res);

        }
        return res;
    }

    public static void main(String[] args) {
        No3_无重复字符的最长子串 v = new No3_无重复字符的最长子串();
        String s = "au";
        int res = v.lengthOfLongestSubstring(s);

        System.out.println(res);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值