leetcode力扣 1004. 最大连续1的个数 III

给定一个二进制数组 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 后,最长的子数组长度为 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 后,最长的子数组长度为 10。

提示:

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

题解:

一道简单的滑动窗口题(双指针), 用两个指针(下标), 维护一个窗口, 窗口满足里面需要满足窗口中0的个数不超过 k 个, 让指针 r 从头遍历到尾, 对窗口的长度取 max 就是答案

ac代码👇

class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        int res = 0;
        
		// l 是滑动窗口的左边界, r 是滑动窗口的右边界, sum 是窗口中 0 的个数
        for (int l = 0, r = 0, sum = 0; r < nums.size(); r ++)
        {
            if (nums[r] == 0) sum ++;

            while (sum > k)
            {
                if (nums[l] == 0) sum --;	// nums[l] == 0, 窗口减少一个 0
                l ++;
            }

            res = max(res, r - l + 1); // qu max
        }
        return res;	// return 答案
    }
};

在我的双指针专栏里还有很多相关题目, 感兴趣的同学可以去看看

总结

滑动窗口算法是一种用于解决子数组或子串问题的有效技巧.

常见类型:

  1. 固定长度的子数组/子串

    • 问题:找到固定长度的子数组或子串,并求其某些特征(如最大或最小值、平均值等)。
    • 例子:给定一个数组和一个整数k,找到长度为k的子数组的最大平均值。
  2. 可变长度的子数组/子串

    • 问题:找到可变长度的子数组或子串,使其满足某些条件(如和等于某个值、包含某些字符等)。
    • 例子:给定一个数组,找到和等于某个值的最长子数组。
  3. 最长或最短的子数组/子串

    • 问题:找到满足某些条件的最长或最短子数组或子串。
    • 例子:给定一个字符串和一个整数k,找到包含最多k个不同字符的最长子串。

本题属于第三种, 满足某个条件的最长子数组

滑动窗口算法通常用于需要在线性时间内解决子数组或子串问题的场景。这些问题的特征通常包括寻找具有特定属性的最长或最短子数组/子串,以及满足某些条件的子数组/子串。这种技术通过动态调整窗口的大小,使得算法能在高效的时间复杂度内找到问题的解。

觉得写的不错的话, 点个赞吧~

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值