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

算法实战:滑动窗口解决水果成篮与字母异位词

综述由AI生成通过水果成篮和找到字符串中所有字母异位词两道经典题目,深入讲解滑动窗口算法的核心思想。重点在于维护一个动态区间,利用左右指针控制窗口大小,配合哈希表或数组统计频次,将时间复杂度从 O(N²) 优化至 O(N)。文章对比了不同数据结构在实现中的性能差异,展示了如何从暴力解法逐步演进到最优解,适合希望提升算法效率的开发者参考。

极光发布于 2026/3/29更新于 2026/6/1419 浏览
算法实战:滑动窗口解决水果成篮与字母异位词

滑动窗口算法实战:水果成篮与字母异位词

滑动窗口是处理连续子数组或子串问题的利器。今天我们通过两道经典题目——'水果成篮'和'找到字符串中所有字母异位词',来拆解它的核心逻辑。

水果成篮

核心思路

这道题要求在一个数组中找到只包含两种元素的最长子数组。乍一看像阅读理解,其实本质就是寻找满足条件的最大窗口。暴力解法需要遍历所有起点,复杂度高达 O(N²),显然不够高效。

我们可以用两个指针 left 和 right 维护一个窗口。关键在于统计窗口内不同元素的种类数。当种类超过 2 时,移动 left 指针缩小窗口,直到满足条件。这里使用定长数组模拟哈希表来记录每种水果的数量,因为数据范围已知且固定。

代码实现
class Solution {
public:
    int totalFruit(vector<int>& fruits) {
        int hash[100001] = {0}; // 记录每种水果的数量
        int ans = 0, kinds = 0; // kinds 记录当前窗口内的水果种类
        for(int left = 0, right = 0; right < fruits.size(); right++) {
            // 进窗口:更新计数,若新种类则增加种类数
            if(hash[fruits[right]]++ == 0) kinds++;
            
            // 出窗口:种类过多时收缩左边界
            while(kinds > 2) {
                if(--hash[fruits[left++]] == 0) kinds--;
            }
            
            // 更新最大长度
            ans = max(ans, right - left + 1);
        }
        return ans;
    }
};

这段代码的时间复杂度降到了 O(N),运行效率显著提升。

找到字符串中所有字母异位词

核心思路

异位词是指由相同字符组成的排列。判断两个字符串是否互为异位词,不需要全排列比较,只需统计字符频次即可。

这是一个典型的固定长度滑动窗口问题。我们需要在字符串 s 中截取长度为 p.size() 的子串,检查其字符频次是否与 p 一致。

初期方案可以使用 unordered_map 存储频次,但考虑到字符集较小(仅小写字母),使用数组模拟哈希表能大幅减少内存分配开销,提升性能。同时,引入一个计数器 kinds 来跟踪有效字符匹配情况,避免每次比较整个数组。

代码实现

初始版本使用哈希表:

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int> ans;
        unordered_map<char,int> hash1, hash2;
        for(auto e : p) hash1[e]++;
        
        for(int left = 0, right = 0; right < s.size(); right++) {
            hash2[s[right]]++;
            if((right - left + 1) > p.size()) {
                char out = s[left];
                if(--hash2[out] == 0) hash2.erase(out);
                left++;
            }
            if(hash1 == hash2) ans.push_back(left);
        }
        return ans;
    }
};

虽然逻辑正确,但哈希表的插入删除操作开销较大。优化后的数组版本如下:

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int> ans;
        int hash1[26], hash2[26] = {0};
        int kinds = 0;
        for(auto e : p) hash1[e - 'a']++;
        
        for(int left = 0, right = 0; right < s.size(); right++) {
            // 进窗口:如果当前字符频次未超过目标,说明是有效字符
            if(++hash2[s[right] - 'a'] <= hash1[s[right] - 'a']) kinds++;
            
            // 出窗口:超出长度需移除左侧字符
            if(right - left + 1 > p.size()) {
                char out = s[left++];
                if(hash2[out - 'a']-- <= hash1[out - 'a']) kinds--;
            }
            
            // 有效字符数等于目标长度,说明找到异位词
            if(kinds == p.size()) ans.push_back(left);
        }
        return ans;
    }
};

注意下标转换 -'a' 以及进出窗口时对 kinds 的维护。这种写法避免了频繁的容器操作,在实际运行中速度更快。


滑动窗口的精髓在于'动'。通过调整窗口边界,我们能在一次遍历中完成复杂的状态维护。掌握这一模式,很多看似棘手的子串问题都能迎刃而解。

目录

  1. 滑动窗口算法实战:水果成篮与字母异位词
  2. 水果成篮
  3. 核心思路
  4. 代码实现
  5. 找到字符串中所有字母异位词
  6. 核心思路
  7. 代码实现
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • C++ 入门指南:发展史、命名空间及输入输出
  • MinGW-w64 安装详细步骤(Windows 下 GCC/G++ 编译器配置)
  • Transformer 架构详解:从 RNN 挑战到自注意力机制与词嵌入
  • TSPR-WEB-LLM-HIC 四元结构 AI 生成式引擎技术架构解析
  • Linux C/C++ 编译参数详解:-I, -l, -L
  • Linux 零基础入门:操作系统核心概念详解
  • 网络安全核心设备与技术原理详解
  • 具身机器人软件系统架构详解
  • Spring Web MVC 入门:从概念到实践
  • 商汤开源 SenseNova-MARS 模型:实现多模态搜索推理新突破
  • Windows 下安装与切换多个 Python 版本的方法
  • JavaScript 生成 UUID 的常见方案与避坑指南
  • AI 产品经理职业路径与核心能力解析
  • 制作 Linux U 盘启动盘:Live 模式与 Rufus 配置
  • WorkBuddy 接入 QQ 机器人配置指南
  • BFS 算法可视化:二叉树层序遍历
  • Java Web 开发入门:核心概念、环境搭建与 Servlet JSP 实战
  • Clawdbot 飞书机器人配置指南与实战避坑
  • 发那科机器人与西门子 PLC 通讯方案:网关与 Modbus TCP 配置及代码
  • GitHub Copilot Agent Skills:打造跨项目 AI 专属工具箱

相关免费在线工具

  • 加密/解密文本

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