解题思路
使用滑动窗口解决:
- 维护一个窗口,窗口内最多包含 个
- 当窗口内 的个数超过 时,移动左边界
- 记录过程中的最大窗口长度
关键点:
- 窗口内的 都可以通过 次操作变成
- 窗口长度就是可以形成的连续 的长度
- 需要不断更新最大长度
代码
#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,计数加1
if (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,计数加1
if (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,计数加1
if nums[right] == 0:
zero_count += 1
# 如果窗口内0的个数超过k,移动左边界
while zero_count > k:
if nums[left] == 0:
zero_count -= 1
left += 1
# 更新最大长度
max_length = max(max_length, right - left + 1)
print(max_length)
if __name__ == "__main__":
solve()
算法及复杂度
- 算法:滑动窗口
- 时间复杂度:,其中 是字符串长度
- 空间复杂度:,只需要常数额外空间