跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

滑动窗口算法实战:最大连续 1 与最小操作数

滑动窗口算法用于解决连续子数组问题。通过两个 LeetCode 题目演示核心思想。第一题寻找最多含 k 个 0 的最长子数组,维护零计数并动态调整窗口边界。第二题利用逆向思维,将两端取数转化为求中间和为总和减 x 的最长子数组,从而最小化操作次数。代码实现包含完整的 C++ 逻辑,涵盖指针移动、条件判断及结果更新。适合算法初学者掌握双指针技巧。

山野来信发布于 2026/3/21更新于 2026/9/762 浏览
滑动窗口算法实战:最大连续 1 与最小操作数

滑动窗口算法实战

1. 1004. 最大连续 1 的个数 III

题目描述

在这里插入图片描述

思路分析

这道题的核心是:找一个最长的子数组,其中最多包含 k 个 0。

经典的 滑动窗口 问题。

为什么用滑动窗口?

  • 我们需要连续区间 → 滑动窗口天然适合
  • 窗口内维护「0 的个数 ≤ k」这个约束
  • 窗口扩张:右指针右移,遇到 0 就计数
  • 窗口收缩:当 0 的个数超过 k,左指针右移直到满足条件
算法流程
1. 初始化:left = 0, zeroCount = 0, maxLen = 0
2. 遍历数组,right 指针右移:
   - 如果 nums[right] == 0,zeroCount++
   - 当 zeroCount > k 时,收缩左边界:
     - 如果 nums[left] == 0,zeroCount--
     - left++
   - 更新 maxLen = max(maxLen, right - left + 1)
3. 返回 maxLen

在这里插入图片描述

代码实现
class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        int zero = 0;
        int ret = 0;
        for (int left = 0, right = 0; right < nums.size(); right++) {
            if (nums[right] == 0) zero++; // 进窗口
            while (zero > k) { // 判断
                if (nums[left++] == 0) zero--; // 出窗口
            }
            ret = max(ret, right - left + 1);
        }
        return ret;
    }
};

2. 1658. 将 x 减到 0 的最小操作数

题目描述

在这里插入图片描述

给定一个整数数组 nums 和整数 x。每次操作可以从数组最左端或最右端移除一个元素,使 x 减去该元素的值。返回将 x 恰好减到 0 的最小操作数,无法实现则返回 -1。

示例:

输入:nums = [1,1,4,2,3], x = 5
输出:2
解释:移除最右端的 3,再移除最右端的 2,x = 5 - 3 - 2 = 0
思路分析

逆向思维 + 滑动窗口

从两端取数 → 等价于找一个中间连续子数组,其和为 total - x。

  • 设数组总和为 sum
  • 问题转化为:找最长的子数组,使其和为 sum - x
  • 最小操作数 = n - 最长子数组长度

为什么?

  • 两端取走的元素和 = x
  • 剩下中间的元素和 = sum - x
  • 操作数最少 → 中间剩余最长
算法流程
1. 计算 target = sum(nums) - x
2. 如果 target < 0,返回 -1(总和都不够减)
3. 滑动窗口找和为 target 的最长子数组
4. 返回 n - maxLen(若 maxLen 有效)

在这里插入图片描述

代码实现
class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        int sum = 0;
        int cmp = 0;
        int ret = -1;
        for (auto e : nums) {
            sum += e;
        }
        int target = sum - x;
        if (target < 0) return -1;
        for (int left = 0, right = 0; right < nums.size(); right++) {
            cmp += nums[right]; // 进窗口
            while (cmp > target) { // 判断
                cmp -= nums[left++]; // 出窗口
            }
            if (cmp == target) { // 更新结果
                ret = max(ret, right - left + 1);
            }
        }
        if (ret == -1) return ret;
        else return nums.size() - ret;
    }
};

目录

  1. 滑动窗口算法实战
  2. 1. 1004. 最大连续 1 的个数 III
  3. 题目描述
  4. 思路分析
  5. 算法流程
  6. 代码实现
  7. 2. 1658. 将 x 减到 0 的最小操作数
  8. 题目描述
  9. 思路分析
  10. 算法流程
  11. 代码实现

更多推荐文章

查看全部
  • 从「AI改变世界」到「AI帮我改Bug」:一个小厂架构师的Agent落地实战
  • CANN 技术栈解析:Python、C++ 及算子开发选型指南
  • 数据结构基础:栈与队列的顺序及链式实现
  • 跨越天堑:机器人脑部药物递送三大技术路径的可转化性分析研究
  • 自然语言处理在医疗健康领域的应用与实战
  • 科技巨头聚焦的 AI Agent 究竟是什么
  • 30 分钟使用 Llama Factory 微调中文大模型
  • 本地部署 LLaMA-Factory 全指南
  • DIY 无人机升压降压电路设计
  • Claude Code 替代方案:OpenCode + GitHub Copilot
  • PostCSS px-to-viewport 移动端适配实战指南
  • 构建企业级 AI 大模型的关键步骤与框架
  • 基于 nanobot 构建轻量级 QQ AI 机器人及搜索模块优化实践
  • 在 Mac 上安装 Java 和 IntelliJ IDEA
  • 地瓜机器人 RDK 系列选型指南:X3、X5、S100、S100P 资源对比
  • Ubuntu 22.04 下基于 ROS2 Humble 的 PX4 无人机仿真环境搭建
  • 低空无人机车辆目标跟踪技术研究
  • 2024 年 AI+ 教育行业发展及研究报告摘要
  • AFFiNE 开源全能知识工作空间使用指南
  • 前端现代化:从传统到现代的技术演进

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online