解题思路

使用滑动窗口解决:

  1. 维护一个窗口,窗口内最多包含
  2. 当窗口内 的个数超过 时,移动左边界
  3. 记录过程中的最大窗口长度

关键点:

  1. 窗口内的 都可以通过 次操作变成
  2. 窗口长度就是可以形成的连续 的长度
  3. 需要不断更新最大长度

代码

#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()

算法及复杂度

  • 算法:滑动窗口
  • 时间复杂度:,其中 是字符串长度
  • 空间复杂度:,只需要常数额外空间