2024年C C++最全【滑动窗口】leetcode904(1),2024年最新字节跳动8年老C C++面试官经验谈

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 使用两个变量,或者称为指针,同时维护,用来当作窗口的边界
  • 右指针右移,然后左指针跟着右移,循环这个动作,直到右指针遍历完整个数组

如下图所示:在我们维护两指针的过程中,像一个窗口在滑动,于是就被起名叫滑动窗口类型的题型。其实也就是双指针。

image-20220323102753644

注意滑动窗口的窗口,此处虽然画的是固定长度,但是对于这类题目来说,可以分为固定长度的滑动窗口问题和不固定长度的滑动窗口

我们为什么需要使用滑动窗口呢?

主要就是效率,我们当然也可以暴力求解一些问题,但是效率是低下的。
引用双指针就能将时间复杂度从O(N^2)变成O(N),这样提高效率是成倍提高的。

话不多说,我们从题目中体会吧!

长度最小的子数组

leetcode209

image-20220323103621562

我们先用暴力求解来体会一些此题:

  • 从第一个数开始求以它为开头的>=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;
    }
}

水果成篮

😭😭😭万恶的水果成篮

这个题目,重在理解题目😭

leetcode904

image-20220323105824820

开始看到题目的时候,《其中first[i]是第i棵树上水果的种类》,这句话我以为是一种=颗树上可以长不同的水果。😭比如first[1]=2,我就以为是第一棵树上有两种水果!!!漏!大漏特漏!

first[1] = 2的真正意义是长的是第二棵树的水果。

image-20220323110232726

也就是说我们要维护的窗口内的数字种类不能超过2,求出最长的窗口大小即可。

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

很难做到真正的技术提升。**

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值