滑动窗口应用场景
- 满足一定条件
- 最长、最短
- 子序列/子串/子数组
简单介绍滑动窗口核心思想
找到最长连续红球子序列
(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);
}
}