LeetCode 1004. 最大连续1的个数 III
LeetCode 1004题 “最大连续1的个数 III” 是一道关于数组和滑动窗口的问题。题目描述如下:
题目描述
给定一个由若干 0
和 1
组成的数组 nums
,以及一个整数 k
。你可以将最多 k
个 0
翻转为 1
。返回经过翻转操作后,数组中连续 1
的最大个数。
示例:
- 输入:
nums = [1,1,1,0,0,0,1,1,1,1,0]
,k = 2
- 输出:
6
- 解释:将中间的两个
0
翻转为1
,得到最长连续1
的子数组[1,1,1,0,0,1,1,1,1,1,1]
,长度为 6。
解题思路:滑动窗口
这道题可以通过滑动窗口算法高效解决。核心思路是:找到一个最长的子数组,其中最多包含 k
个 0
。如果窗口内的 0
数量超过 k
,则需要收缩窗口左侧。
具体步骤如下:
- 扩展窗口:不断向右移动右指针
right
,并统计窗口内0
的数量。 - 收缩窗口:如果窗口内
0
的数量超过k
,则向右移动左指针left
,并减少窗口内0
的数量,直到窗口内0
的数量不超过k
。 - 记录最大长度:在每次窗口合法(
0
的数量 ≤k
)时,更新最大长度。
代码实现
以下是使用滑动窗口解决该问题的代码:
class Solution {
public:int longestOnes(vector<int>& nums, int k) {int n = nums.size();int left = 0, right = 0;int zeroCount = 0; // 记录窗口内0的数量int maxLen = 0; // 记录最大连续1的长度while (right < n) {// 扩展窗口:如果当前元素是0,增加zeroCountif (nums[right] == 0) {zeroCount++;}// 收缩窗口:如果窗口内0的数量超过kwhile (zeroCount > k) {if (nums[left] == 0) {zeroCount--;}left++;}// 更新最大长度maxLen = max(maxLen, right - left + 1);right++;}return maxLen;}
};
复杂度分析
- 时间复杂度:O(n),其中 n 是数组的长度。每个元素最多被访问两次(右指针和左指针各一次)。
- 空间复杂度:O(1),只需要常数级的额外空间。
关键点解释
- 窗口合法性:窗口内
0
的数量 ≤k
时,窗口合法,可以计算长度。 - 动态调整:通过移动左指针
left
,动态调整窗口大小,确保窗口内0
的数量始终合法。 - 最大长度更新:每次窗口合法时,计算当前窗口长度
right - left + 1
,并更新最大值。
这种滑动窗口的思想在处理数组中的子数组问题时非常常见,尤其是需要满足特定条件的最长/最短子数组问题。