数组 - 滑动窗口
滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果
窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)
代码实现为:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left = 0;
int sum = 0;
int res = Integer.MAX_VALUE;
for(int right = 0;right<nums.length;right++){
sum += nums[right];
while(sum>=target){
//注意在改变起始位置时,要先记录当前res
res = Math.min(res,right-left+1);
sum -= nums[left];
left++;
}
}
return res==Integer.MAX_VALUE?0:res;
}
}
代码实现为:
class Solution {
public int totalFruit(int[] fruits) {
//哈希表记录水果种类出现的数目
Map<Integer,Integer> hashmap = new HashMap<>();
int left = 0;
int res = 0;
for(int right = 0;right<fruits.length;right++){
hashmap.put(fruits[right],hashmap.getOrDefault(fruits[right],0)+1);
while(hashmap.size()>2){
//注意步骤的顺序,要先把现有数据处理好再移动起始位置
hashmap.put(fruits[left],hashmap.get(fruits[left])-1);
if(hashmap.get(fruits[left])==0){
hashmap.remove(fruits[left]);
}
left++;
}
res = Math.max(res,right-left+1);
}
return res;
}
}
代码实现为:
class Solution {
public String minWindow(String s, String t) {
//利用整数数组存放char,char的int值范围是0-127
int[] need = new int[128];
int[] window = new int[128];
for(int i = 0;i<t.length();i++){
need[t.charAt(i)]++ ;
}
int left = 0;
int right = 0;
String res = "";
//当前字符数
int count = 0;
int minLen = s.length()+1;
while(right<s.length()){
char ch = s.charAt(right);
window[ch]++;
//因为若need中同个字符的数量小于窗口中的,则已满足条件,多的不能当做有效字符
if(need[ch]>0 && need[ch]>=window[ch]){
count++;
}
//改变起始位置的条件
while(t.length()==count){
char rem = s.charAt(left);
if(need[rem]>0 && need[rem]>=window[rem]){
count--;
}
if(right-left+1<minLen){
minLen = right-left+1;
res = s.substring(left,right+1);
}
left++;
window[rem]--;
}
right++;
}
return res;
}
}