XingHuiSamaの宝藏之地
首页项目归档照片墙音乐灵境说说杂谈友链关于
封面

Leetcode一百题——无重复字符的最长子串

2026-04-12 14:14:20
# Leetcode
# 工作
# 算法
# 题解

给定一个字符串 s ,请你找出其中不含有重复字符的 最长的长度。

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。注意 "bca" 和 "cab" 也是正确答案。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成

这个也是滑动窗口加快慢指针解出来的。

1. 算法核心思想:带频率监控的滑动窗口

该算法采用滑动窗口模型扫描整个字符串。与常规的直接跨越边界不同,此解法通过一个独立的 len 变量精确追踪当前有效窗口的长度,并使用 unordered_map 严格监控窗口内每个字符的出现频率。

  • 状态 A(无冲突扩张):当即将进入窗口的右侧字符不存在于哈希表中时,窗口安全向右扩张,同时增加长度记录。
  • 状态 B(冲突逐级收缩):当发现右侧字符已存在于哈希表中时,右边界暂停移动。左边界开始逐个向右收缩,并在哈希表中同步扣减移出字符的频率,直到触发冲突的重复字符被完全移出窗口。
class 无意义最长子串 {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char, int> map;
        int len = 0;
        int maxLen = 0;

        int front = 0;
        int back = 0;

        while (back < s.size()) {
            char c = s[back];
            if (map.find(c) == map.end()) {
                map[c]++;
                back++;
                len++;
            }
            else {
                map[s[front]]--;
                if (map[s[front]] == 0) {
                    map.erase(s[front]);
                }
                len--;
                front++;
            }

            if (len > maxLen) {
                maxLen = len;
            }
        }

        return maxLen;
    }
};

2. 复杂度剖析

  • 时间复杂度:O(N)。虽然代码中有分支嵌套,但在最坏的情况下,字符串中的每个字符也最多只会被右指针进入一次,被左指针移出一次。哈希表的增删改查均摊耗时都是常数级,整体运行效率保持着完美的线性节奏。
  • 空间复杂度:O(Σ)。这里的 Σ 代表字符集的总数。哈希表的体积被严格限制在当前窗口的不重复字符数量内。对于常规的 ASCII 字符,最多只占用 128 个常数级别的额外空间。
avatar

XingHuiSama

在代码、学术与分子动力学模拟间穿梭的普通人。近期正埋头于 GROMACS 模拟研究与神经网络计算。

RECOMMENDED

GROMACS 2025 分子动力学模拟初探2222

2026-03-24 07:00:45

Computational Chemistry Tool 工具二介绍

2026-04-01 07:00:23

Leetcode一百题——字母异位词分组

2026-04-07 15:34:18

Table of Contents