今后遇到滑动窗口问题都可先按该模板来写
1. leetcode:3. Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters.
Example 1:
Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc"
, with the length of 3.
代码如下:
这是一个滑动窗口+查找表:也就是滑动窗口中的数据用数组、set、map等等数据结构来保存
class Solution {
public int lengthOfLongestSubstring(String s) {
int[] freq = new int[256];//在l 到 r之间维护一个数组来表示滑动窗口,
//也可以定义一个hasnmap来维持一个窗口
int l = 0, r = -1;
int res = 0;
while(l< s.length()){
if(r+1 < s.length() && freq[s.charAt(r+1)] == 0){//滑动窗口中没出现过该字母
freq[s.charAt(++r)] ++;
}else{//滑动窗口中出现过该字母,则进行窗口移动
freq[s.charAt(l++)] --;
}
res = Math.max(res, r-l+1);
}
return res;
}
}
2.220. Contains Duplicate III Given an array of integers, find out whether there are two distinct indices i and j in the array such that the absolute difference between nums[i] and nums[j] is at most t and the absolute difference between i and j is at most k.
Example 1:
Input: nums = [1,2,3,1], k = 3, t = 0 Output: true
这是一个滑动窗口+查找表(滑动窗口长度是可变的):
代码如下:
public class Solution {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (nums == null || nums.length == 0 || k <= 0) {
return false;
}
TreeSet<Integer> values = new TreeSet<>();
for (int ind = 0; ind < nums.length; ind++) {
Integer floor = values.floor(nums[ind] + t);
Integer ceil = values.ceiling(nums[ind] - t);
if ((floor != null && floor >= nums[ind])
|| (ceil != null && ceil <= nums[ind])) {
return true;
}
values.add(nums[ind]);
if (ind >= k) {
values.remove(nums[ind - k]);
}
}
return false;
}
}
3.219. Contains Duplicate II
Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.
Example 1:
Input: nums = [1,2,3,1], k = 3 Output: true
这是一个滑动窗口+查找表(滑动窗口长度是不可变的):
代码如下:
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
Set<Integer> set = new TreeSet<Integer>();
for(int i=0;i<nums.length; i++){
if(i>k){
set.remove(nums[i-k-1]);
}
if(!set.add(nums[i])){
return true;
}
}
return false;
}
}
3.209. Minimum Size Subarray Sum
Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.
Example:
Input:s = 7, nums = [2,3,1,2,4,3]
Output: 2 Explanation: the subarray[4,3]
has the minimal length under the problem constraint.
这是一个完全用滑动窗口来解决的问题(同时滑动窗口长度是可变的)
代码如下:
class Solution {
public int minSubArrayLen(int s, int[] a) {
int l =0, r=-1,res =a.length+1 , sum =0;
while(l<a.length){
if(r+1 < a.length && sum<s){
sum += a[++r];
}else{
sum -= a[l++];
}
if( sum>= s){
res = Math.min(res, r-l+1);
}
}
return res == a.length+1 ? 0:res;
}
}
//或者
class Solution {
public int minSubArrayLen(int s, int[] a) {
if (a == null || a.length == 0)
return 0;
int left = 0, right = 0, sum = 0, min = Integer.MAX_VALUE;
while (right < a.length) {
sum += a[right++];
while (sum >= s) { //是while而不是if
min = Math.min(min, right - left);
sum -= a[left++];
}
}
return min == Integer.MAX_VALUE ? 0 : min;
}
}
可以分为两类:1.滑动窗口
2.滑动窗口+查找表(也就是滑动窗口用什么数据结构来存储一般有数组、set、map),同时滑动窗口长度可以 分为可变与不可变
根据规律滑动窗口问题可写一个模板如下:(适用于滑动窗口 或者 滑动窗口+查找表同时滑动窗口长度可变)
class Solution {
public int minSubArrayLen(int s, int[] a) {
int l =0, r=-1 .....;//定义滑动窗口两下标
while( l<输入长度 ){
if(r+1 < a.length && 另一个条件){// r+1要小于输入长度
// 只做l++ 或者 ++r相关操作
}else{
//只做l++ 或者 ++r相关操作
}
// 做除了l++ 或者 r++之外的其他操作
}
}
}