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

滑动窗口算法:无重复字符的最长子串(数组模拟哈希表)

讲解使用滑动窗口结合数组模拟哈希表解决无重复字符最长子串问题。通过双指针维护窗口,统计字符频次,当窗口内出现重复字符时收缩左指针,动态更新最大长度。相比暴力解法,时间复杂度从 O(N^2) 优化至 O(N)。

并发大师发布于 2026/2/4更新于 2026/9/107.1K 浏览
滑动窗口算法:无重复字符的最长子串(数组模拟哈希表)

文章配图

上期参考代码

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int n = nums.size();
        int left = 0, right = 0, length = n + 1, sum = 0;
        while (right < nums.size()) {
            sum += nums[right];
            while (sum >= target) {
                length = min(right - left + 1, length);
                sum -= nums[left++];
            }
            right++;
        }
        return length == n + 1 ? 0 : length;
    }
};

本期题目

无重复字符的最长子串

读题

文章配图

要点

  • 无重复
  • 需要统计元素出现的次数(哈希表)
  • 最长
  • 子串(必须是连续的,示例三已强调)

解题

暴力解法

双重循环遍历元素 + 哈希表统计元素出现次数

在遍历元素的过程中,将元素扔进哈希表统计它出现的次数,内层如果遍历到的元素出现次数大于 1,直接跳过接下来的遍历过程,外循环开始下一次遍历。

代码:
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n = s.size(), ret = 0;
        int i, j;
        for (i = 0; i < n; i++) {
            int hash[128] = {0}; // 使用数组来模拟哈希表,每次外循环刷新
            for (j = i; j < n; j++) {
                hash[s[j]]++;
                if (hash[s[j]] > 1) {
                    ret = max(ret, j - i);
                    break; // 有重复字符的情况
                }
            }
            ret = max(ret, j - i); // 处理无重复字符的情况
        }
        return ret;
    }
};

时间复杂度 O(N^2),能过,但是还能优化。

优解

摸索

分析上述暴力解法,我们发现,每次统计数据的时候我们都要刷新哈希表,然后重新统计,之前统计的数据有部分还是需要重新再统计一遍,资源大大浪费,我们可以尝试找到一种方法,对之前的统计数据进行维护,提高代码效率。

我们先用双指针来模拟并改进暴力解法:

文章配图

通过模拟我们发现,双指针可灵活维护统计数据,且双指针是同向移动的,同向双指针,也就是我们的滑动窗口,可以直接把嵌套 for 的 N^2 时间复杂度干成 N。

发现了同向双指针,我们就可以使用滑动窗口的固定套路来写代码啦

文章配图

代码逻辑
  1. 初始化双指针
  2. 进窗口:把元素扔进哈希表统计出现次数
  3. 条件判断:出现次数>1,开始出窗口
  4. 更新结果:出完窗口之后,子串一定是符合条件的,此时更新 ret
代码:
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n = s.size();
        int left = 0, right = 0, ret = 0;
        int hash[128] = {0}; // 使用数组模拟哈希表
        
        while (right < n) {
            // 进窗口:统计当前字符
            hash[s[right]]++;
            
            // 条件判断:如果当前字符重复,收缩左指针直到不重复
            while (hash[s[right]] > 1) {
                hash[s[left]]--;
                left++;
            }
            
            // 更新结果:记录最大长度
            ret = max(ret, right - left + 1);
            right++;
        }
        return ret;
    }
};

下期预告

最大连续 1 的个数 III

目录

  1. 上期参考代码
  2. 本期题目
  3. 读题
  4. 要点
  5. 解题
  6. 暴力解法
  7. 双重循环遍历元素 + 哈希表统计元素出现次数
  8. 代码:
  9. 优解
  10. 摸索
  11. 代码逻辑
  12. 代码:
  13. 下期预告

更多推荐文章

查看全部
  • PyCharm 安装与配置完整指南
  • Go 语言工程师如何进阶为云原生高级开发工程师
  • GCC 14与C++26并发新特性深度解析
  • 被工具定义的编程时代:VS Code 与 JetBrains 效率指南
  • Cookie 与 Session:Web 用户状态管理机制解析
  • 前缀和解子数组计数:和为 K 与可被 K 整除
  • Stable Diffusion 皮革服装 LoRA 模型部署与使用指南
  • Rust 异步 Web 框架 Axum:核心原理与实战进阶
  • Flutter 基础组件:BottomNavigationBar 与 TabBar 多页切换
  • 使用 for...of 实现异步任务串行执行
  • 数据结构核心:KMP 算法、Trie 树与并查集详解
  • Java Map 常用方法与核心实现类详解
  • OpenClaw:从认知到行动的智能体框架解析
  • 基于星辰 RPA 实现小红书自动发文机器人
  • 开源电路板查看器 OpenBoardView:.brd 文件解析工具
  • Qwen3-VL 法律场景长文档 OCR 结构化解析教程
  • 滑动窗口算法详解与 LeetCode 高频题目解题模板
  • VS Code 远程连接服务器后 GitHub Copilot 无法使用的解决方案
  • Windows 11 安装 MySQL 8.0 完整教程
  • OSS 权限控制实战:ACL、RAM、Bucket Policy 与错误排查

相关免费在线工具

  • 加密/解密文本

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