Appearance
双指针之滑动指针
代码随想录管这叫滑动窗口,但是我想区别于单调队列的滑动窗口,自命名为滑动指针!
滑动指针
滑动指针一般用于求符合某种条件的最长或最短的子序列。
在暴力解法中,是一个for循环滑动窗口的起始位置,一个for循环为滑动窗口的终止位置,用两个for循环完成了一个不断搜索区间的过程,时间复杂度为。
而滑动指针,就是不断的调节子序列的起始位置和终止位置,维护窗口的状态,从而得出我们要想的结果,时间复杂度为。
滑动指针的实现需要考虑如下问题:
如何移动窗口的起始位置?
如何移动窗口的结束位置?
维护哪些数据?
题目
209.长度最小的子数组
- 初始时,起始指针和终止指针都位于序列首元素
- 终止指针不断后移直到子序列的和大于target,更新子序列和
- 起始指针不断后移直到子序列的和小于target,更新子序列和与最小长度
- 重复2和3,直到终止指针到达序列末尾
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int i=0,j=0,s=0,ans=0x3f3f3f3f;
while(j<nums.size()){
s+=nums[j++];
while(s>=target && i<j){
ans=ans<=(j-i)?ans:(j-i);
s-=nums[i++];
}
}
if(ans==0x3f3f3f3f) return 0;
else return ans;
}
};
904.水果成篮
- 初始时,起始指针和终止指针都位于序列首元素。用两个变量记录当前选择的水果种类,初始化为-1。
- 终止指针不断后移直到遇到未记录的水果种类,更新两个用于记录的变量
- 起始指针从终止指针前向前移动直到遇到不一样的水果种类,更新最大数目
- 重复2和3,直到终止指针到达序列末尾
class Solution {
public:
int totalFruit(vector<int>& fruits) {
if(fruits.size()<=2) return fruits.size();
int i=0,j=0,ans=2;
int h=-1,t=-1;
for(;j<fruits.size();j++){
if(fruits[j]!=h && fruits[j]!=t){
if(h==-1) h=fruits[j];
else if(t==-1) t=fruits[j];
else{
ans=ans>=(j-i)?ans:(j-i);
h=fruits[j-1];
t=fruits[j];
i=j-1;
while(i>=0 && fruits[i]==h) i--;
i++;
}
}
}
return ans>=(j-i)?ans:(j-i);
}
};
76.最小覆盖子串
(未完成)