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

滑动窗口算法详解:水果成篮问题

滑动窗口算法适用于解决连续区间内最多包含两种元素的最大长度问题。核心思路是维护左右指针及哈希表统计窗口内水果频次,当种类超过限制时移动左指针收缩窗口,直至满足条件并更新最大长度。文章提供 C++ 容器版与数组模拟哈希表版两种实现方案,展示了从初始化到循环结束的具体流程。

GopherDev发布于 2026/3/29更新于 2026/10/2687 浏览
滑动窗口算法详解:水果成篮问题

13 水果成篮

题目描述

题目图片

示例

示例图片

解法(滑动窗口)

算法思路

研究的对象是一段连续的区间,可以使用【滑动窗口】思想来解决问题。

让滑动窗口满足:窗口内水果的种类只有两种。

做法:右端水果进入窗口的时候,用哈希表统计这个水果的频次。这个水果进来后,判断哈希表的大小:

  • 如果大小超过 2:说明窗口内水果种类超过了两种。那么就从最左侧开始依次将水果划出窗口,直到哈希表的大小小于 2,然后更新结果;
  • 如果没有超过 2,说明当前窗口内水果的种类不超过两种,直到更新结果 len。

算法流程

  1. 初始化哈希表 hash 来统计窗口内水果的种类和数量;
  2. 初始化变量:左右指针 left = 0,right = 0,记录结果的变量 len = 0;
  3. 当 right 小于数组大小的时候,一直执行下列循环:
    • 将当前水果放入哈希表
    • 判断当前水果进来后,哈希表的大小:
      • 如果超过 2:
        • 将左侧元素滑出窗口,并且在哈希表中将该元素的频次减一;
        • 如果这个元素的频次减一之后变成了 0,就把该元素从哈希表中删除;
        • 重复上述两个过程,直到哈希表中的大小不超过 2;
    • 更新结果 len;
    • right++,让下一个元素进入窗口;
  4. 循环结束后,len 存的就是最终结果。

C++ 代码演示:方法一 (使用容器)

class Solution {
public:
    int totalFruit(vector<int>& fruits) {
        // 方法一:使用容器 (如果对哈希掌握不是很好可以看下面方法二)
        unordered_map<int, int> hash;
        // 统计窗口内出现水果的种类
        int left = 0;
        int right = 0;
         len = ;
        (right = ; right < fruits.(); right++) {
            hash[fruits[right]]++;
            
            (hash.() > ) 
            {
                hash[fruits[left]]--;
                
                (hash[fruits[left]] == ) {
                    hash.(fruits[left]);
                }
                left++;
            }
            len = (len, right - left + );
            
        }
         len;
    }
};
int
0
for
0
size
// 进窗口
while
size
2
// 判断
// 出窗口
if
0
erase
max
1
// 更新结果
return

C++ 代码演示:方法二 (用数组模拟哈希表)

class Solution {
public:
    int totalFruit(vector<int>& fruits) {
        // 方法二:用数组模拟哈希表 (只需要了解哈希可以对数据存放的次数进行计数即可)
        int hash[100001] = { 0 };// 根据题目提示可知水果种类最多不超过 100000
        int left = 0;
        int right = 0;
        int len = 0;
        int kinds = 0;
        // 用一个新变量来维护水果种类
        for(right = 0; right < fruits.size(); right++) {
            if(hash[fruits[right]] == 0) {
                kinds++;
            }
            hash[fruits[right]]++;
            // 进窗口
            while(kinds > 2) // 判断
            {
                hash[fruits[left]]--;
                // 出窗口
                if(hash[fruits[left]] == 0) {
                    kinds--;
                }
                left++;
            }
            len = max(len, right - left + 1);
            // 更新结果
        }
        return len;
    }
};

算法总结及流程解析

流程图 1

流程图 2

目录

  1. 13 水果成篮
  2. 题目描述
  3. 示例
  4. 解法(滑动窗口)
  5. 算法思路
  6. 算法流程
  7. C++ 代码演示:方法一 (使用容器)
  8. C++ 代码演示:方法二 (用数组模拟哈希表)
  9. 算法总结及流程解析

更多推荐文章

查看全部
  • Python 语言概述:核心特性、应用场景与学习价值
  • DeepSeek 各版本详解:从 V1 到 R1 的演进与选型指南
  • Python 数据库操作指南:使用 SQLAlchemy ORM 实现高效开发
  • OpenClaw Gateway 服务运维:启动、停止与监控实践
  • C++ 在线五子棋对战项目网页版开发详解
  • Docker 基础概念与常用命令实战
  • 超级对齐全面综述:构建安全可靠的未来
  • AI 热榜深度解析:平台生态、多智能体与评测体系新趋势
  • LeetCode 92 链表区间反转:递归实现与哨兵技巧详解
  • WebArena:一个真实的网页环境,用于构建自主智能体
  • VSCode 远程连接时 GitHub Copilot Chat 图标缺失修复
  • JS 流程控制:条件与循环核心用法
  • 构建 AI Agent 框架:从规划到执行的全流程解析
  • Tailscale 零信任网络搭建:Linux/Windows/macOS 多平台配置教程
  • 基于 Vue3 与 Django 的线上文献阅览平台
  • n8n Docker Compose 部署指南:官方与中文镜像配置详解
  • CTFshow PWN 059 详解:64 位架构下 Ret2Shellcode 进阶与指令集适配
  • IntelliJ IDEA 切换 JDK 版本完整指南
  • 前端监控实践:错误、性能与行为监控指南
  • Windows 环境 Git 安装与配置指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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