滑动窗口

滑动窗口

模板

本质上是双指针(快慢指针)的一种应用,可以理解为用两个指针维护一个区间,动态调整区间范围以满足题目要求。

常用于查找满足某些条件的连续子区间。

固定长度滑动窗口

left = 0  # 窗口左边界
right = 0  # 窗口右边界while right < len(nums):# 将当前元素加入窗口window.append(nums[right])# 判断当前窗口长度是否达到 window_sizeif right - left + 1 >= window_size:# 在窗口长度达到要求时,进行答案的统计或更新# ... 这里根据题目需求维护/更新答案# 移除窗口最左侧元素,窗口向右滑动window.popleft()left += 1  # 左指针右移,缩小窗口长度,保持窗口长度为 window_size# 右指针右移,扩大窗口right += 1

不定长度滑动窗口

# 初始化左右指针,均指向数组起始位置
left = 0
right = 0# 主循环,右指针遍历整个数组
while right < len(nums):# 将当前右指针指向的元素加入窗口window.append(nums[right])# 当窗口不满足题目要求时,缩小窗口(移动左指针)while 窗口需要缩小:# 此处可根据题意维护/更新答案window.popleft()  # 移除左边界元素left += 1         # 左指针右移,缩小窗口# 此处可根据题意维护/更新答案(如记录最大/最小窗口等)# 右指针右移,扩大窗口right += 1

题目

1、拆分子串,长度限定在[min, max]

思路:双指针

import java.util.ArrayList;
import java.util.List;public class Main {public static void main(String[] args) {String str = "abcdefghijk";System.out.println(new Main().getAllSub(str, 6, 12));System.out.println(new Main().getAllSub_1(str, 6, 12));}List<String> getAllSub_1(String str, int min, int max) {List<String> res = new ArrayList<>();int n = str.length();for (int i = 0; i < n; i++) {for (int j = i; j < Math.min(n, i + max); j++) {int len = j - i + 1;if (len >= min && len <= max) {res.add(str.substring(i, j + 1));}}}return res;}List<String> getAllSub(String str, int min, int max) {List<String> res = new ArrayList<>();int n = str.length();int left = 0;while (left < n) {int right = left;while (right < n) {int len = right - left + 1;if (len >= min && len <= max) {res.add(str.substring(left, right + 1));} else if (len > max) {break;}right++;}left++;}return res;}
}

2、1343. 大小为 K 且平均值大于等于阈值的子数组数目

给你一个整数数组 arr 和两个整数 k 和 threshold 。
请你返回长度为 k 且平均值大于等于 threshold 的子数组数目。

leetcode-1343

class Solution {public int numOfSubarrays(int[] arr, int k, int threshold) {int left=0,right=0,window_size=0;int res = 0;while (right < arr.length) {window_size += arr[right];if (right-left+1 >= k) {if (window_size >= k*threshold) {res++;}window_size -= arr[left];left++;}right++;}return res;}
}

3、无重复字符的最长子串

给定一个字符串s,请你找出其中不含有重复字符的最长子串的长度。

子字符串:是字符串中连续的、非空的字符序列。

leetcode-3

class Solution {public int lengthOfLongestSubstring(String s) {int left=0,right=0;int res = 0;Map<Character,Integer> map=new HashMap<>();while (right<s.length()) {char c = s.charAt(right);right++;map.put(c, map.getOrDefault(c, 0)+1);while (map.get(c) > 1) {char temp = s.charAt(left);map.put(temp, map.get(temp)-1);left++;}res = Math.max(res, right - left);}return res;}
}

参考

https://algo.itcharge.cn/01_array/01_16_array_sliding_window/