题目
题目链接
解题思路
使用滑动窗口解决:
- 维护一个窗口,窗口内最多包含 \(k\) 个 \(0\)
- 当窗口内 \(0\) 的个数超过 \(k\) 时,移动左边界
- 记录过程中的最大窗口长度
关键点:
- 窗口内的 \(0\) 都可以通过 \(k\) 次操作变成 \(1\)
- 窗口长度就是可以形成的连续 \(1\) 的长度
- 需要不断更新最大长度
代码
#include <iostream>
#include <vector>
using namespace std;int main() {// 读取输入int n, k;cin >> n >> k;vector<int> nums(n);for (int i = 0; i < n; i++) {cin >> nums[i];}// 滑动窗口int left = 0; // 左边界int zeroCount = 0; // 窗口内0的个数int maxLength = 0; // 最大长度// 右边界不断扩展for (int right = 0; right < n; right++) {// 如果遇到0,计数加1if (nums[right] == 0) {zeroCount++;}// 如果窗口内0的个数超过k,移动左边界while (zeroCount > k) {if (nums[left] == 0) {zeroCount--;}left++;}// 更新最大长度maxLength = max(maxLength, right - left + 1);}cout << maxLength << endl;return 0;
}
import java.util.*;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);// 读取输入int n = sc.nextInt();int k = sc.nextInt();int[] nums = new int[n];for (int i = 0; i < n; i++) {nums[i] = sc.nextInt();}// 滑动窗口int left = 0; // 左边界int zeroCount = 0; // 窗口内0的个数int maxLength = 0; // 最大长度// 右边界不断扩展for (int right = 0; right < n; right++) {// 如果遇到0,计数加1if (nums[right] == 0) {zeroCount++;}// 如果窗口内0的个数超过k,移动左边界while (zeroCount > k) {if (nums[left] == 0) {zeroCount--;}left++;}// 更新最大长度maxLength = Math.max(maxLength, right - left + 1);}System.out.println(maxLength);}
}
def solve():# 读取输入n, k = map(int, input().split())nums = list(map(int, input().split()))# 滑动窗口left = 0 # 左边界zero_count = 0 # 窗口内0的个数max_length = 0 # 最大长度# 右边界不断扩展for right in range(n):# 如果遇到0,计数加1if nums[right] == 0:zero_count += 1# 如果窗口内0的个数超过k,移动左边界while zero_count > k:if nums[left] == 0:zero_count -= 1left += 1# 更新最大长度max_length = max(max_length, right - left + 1)print(max_length)if __name__ == "__main__":solve()
算法及复杂度
- 算法:滑动窗口
- 时间复杂度:\(\mathcal{O}(n)\),其中 \(n\)是字符串长度
- 空间复杂度:\(\mathcal{O}(1)\),只需要常数额外空间