• 滑动窗口实例3(最大连续1的个数Ⅲ)


    题目:

    给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。

    示例 1:

    输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
    输出:6
    解释:[1,1,1,0,0,1,1,1,1,1,1]
    粗体数字从 0 翻转到 1,最长的子数组长度为 6。

    示例 2:

    输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
    输出:10
    解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
    粗体数字从 0 翻转到 1,最长的子数组长度为 10。

    提示:

    • 1 <= nums.length <= 105
    • nums[i] 不是 0 就是 1
    • 0 <= k <= nums.length

    算法原理:

    题目可以解析成另一层意思:求最长的子数组区间,要求区间内0的个数不超过k个

    若是连续区间,我们可以考虑用滑动窗口来解题

    滑动窗口其实就是同向双指针,left指针和right指针只会向前走,不会回退

    1 left=0(左边界) right=0(指向待加入窗口中的元素) zero变量统计区间中0出现的次数

    2 进窗口:right指向的元素如果是1,则right只管++,若是0,则zero++

    3 判断:若是当right指向的元素加入窗口后(nums[right]是0),zero超过k,则要出窗口了,即当前元素作为左边界能够延展的长度已是极限了,要换新的左边界

    4 出窗口:left不断++,直至zero不再超过k,停下来的left就是新的左边界

                      暴力解法中新的左边界直接就是下一个元素,但其实暴力解法枚举左边界的做法会枚举出毫无意义的情况,如

    代码实现:

     

    1. class Solution
    2. {
    3. public:
    4. int longestOnes(vector<int>& nums, int k)
    5. {
    6. int left = 0;
    7. int right = 0;
    8. int zero = 0;
    9. int n = nums.size();
    10. int ret = 0;
    11. while(right
    12. {
    13. if(nums[right]==0)//进窗口
    14. {
    15. zero++;
    16. }
    17. while(zero>k)//判断
    18. {
    19. if(nums[left++]==0)//出窗口
    20. {
    21. zero--;
    22. }
    23. }
    24. ret = max(ret,right-left+1);
    25. right++;
    26. }
    27. return ret;
    28. }
    29. };

  • 相关阅读:
    6.1 线性空间
    厦门大学《信号与系统》考试大纲
    一文带你了解 Spring 的@Enablexxx 注解
    vue相关面试题:computed和watch区别
    和为S的连续正数序列
    想当测试Leader,这6项技能你会吗?
    渲染噪点多怎么解决?渲染噪点多的原因及处理方法
    微服务架构整体分析:优势与挑战
    三星在又一个市场击败中国手机,继续称霸全球,中国市场没那么重要
    【Houdini】如何使用Houdini渲染流体?
  • 原文地址:https://blog.csdn.net/weixin_73142957/article/details/132616550