网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
- 使用两个变量,或者称为指针,同时维护,用来当作窗口的边界
- 右指针右移,然后左指针跟着右移,循环这个动作,直到右指针遍历完整个数组
如下图所示:在我们维护两指针的过程中,像一个窗口在滑动,于是就被起名叫滑动窗口类型的题型。其实也就是双指针。
注意滑动窗口的窗口,此处虽然画的是固定长度,但是对于这类题目来说,可以分为固定长度的滑动窗口问题和不固定长度的滑动窗口
我们为什么需要使用滑动窗口呢?
主要就是效率,我们当然也可以暴力求解一些问题,但是效率是低下的。
引用双指针就能将时间复杂度从O(N^2)变成O(N),这样提高效率是成倍提高的。
话不多说,我们从题目中体会吧!
长度最小的子数组
我们先用暴力求解来体会一些此题:
- 从第一个数开始求以它为开头的>=target连续子数组
- 重复上述过程到第二个数/第三个数/第四个数/…
- 找出最小长度子数组
我们以第一个示例为例子
第一次是2开头的:[2,3,1,2] 和为8 >=7 长度为4
第二次是3开头的:[3,1,2,4] 和为10 >= 7 长度为4
第三次是1开头的:[1,2,4] 和为 7 >= 7 长度为3
第四次是2开头的:[2,4,3] 和为9 >= 7 长度为3
第五次是4开头的:[4,3] 和为 7 >= 7 长度为2
第六次是3开头:不满足 >=7
我们定义一个minCount,每次记录一个子数组的长度就与之比较,取小赋值给minCount。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int minCount = 10000;
int count = 0;
int sum = 0;
for(int i = 0; i < nums.length; i++) {
sum = 0;
for(int j = i; j < nums.length; j++) {
sum+=nums[j];
if(sum >= target) {
count = j - i + 1;
break;
}
}
if(minCount > count){
minCount = count;
}
}
return minCount;
}
}
接下来来看看滑动窗口的写法:
与暴力的思路差不多
只不过在找到某一个子数组之后,就将左指针++,找下一个子窗口。同时sum减去未加加前的左指针值。
注意此处就是导致时间复杂度的关键。暴力中我们每一次循环都要重新计算sum,此处我们并没有,sum加过的元素,一直在sum中,直到左指针指向这些元素,才被减去,也就是我们虽然在两重循环中,但是对元素操作也只是两次而已,时间复杂度是O(2N)
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left = 0;
int right = 0;
int sum = 0;
int minLen = 10000;
int len = 0;
while(right < nums.length){
sum+=nums[right];
right++;
while(sum >=target){
minLen = Math.min(minLen,right - left);
sum = sum - nums[left];
left++;
}
}
if(minLen == 10000){
return 0;
}
return minLen;
}
}
水果成篮
😭😭😭万恶的水果成篮
这个题目,重在理解题目😭
开始看到题目的时候,《其中first[i]是第i棵树上水果的种类》,这句话我以为是一种=颗树上可以长不同的水果。😭比如first[1]=2,我就以为是第一棵树上有两种水果!!!漏!大漏特漏!
first[1] = 2的真正意义是长的是第二棵树的水果。
也就是说我们要维护的窗口内的数字种类不能超过2,求出最长的窗口大小即可。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
很难做到真正的技术提升。**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!