【LeetCode】3. 无重复字符的最长子串

【LeetCode】3. 无重复字符的最长子串

题目

【LeetCode】3. 无重复字符的最长子串

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

示例 1:

输入:s = "abcabcbb"

输出:3

解释:因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入:s = "bbbbb"

输出:1

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

示例 3:

输入:s = "pwwkew"

输出:3

解释:因为无重复字符的最长子串是 "wke",所以其长度为 3。

请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

提示:

0 <= s.length <= 5 * 104

s 由英文字母、数字、符号和空格组成

解题思路

核心要点:

  • 子串是连续的字符序列,不同于子序列
  • 需要找到不包含重复字符的最长子串长度
  • 高效判断字符是否重复是关键

最有效的解法是滑动窗口法 结合哈希集合

  1. 使用左右两个指针表示当前窗口的边界
  2. 右指针不断向右移动,将字符加入哈希集合
  3. 当遇到重复字符时,移动左指针并从集合中移除相应字符,直到窗口中没有重复字符
  4. 每次移动后计算当前窗口长度,并更新最大长度

这种方法只需一次遍历,时间复杂度为O(n),非常高效。

代码实现

java 复制代码
import java.util.HashSet;
import java.util.Set;

public class LongestSubstring {
    public int lengthOfLongestSubstring(String s) {
        // 哈希集合,用于存储当前窗口中的字符
        Set<Character> set = new HashSet<>();
        int n = s.length();
        // 右指针,初始值为 -1,相当于在字符串的左边界的左侧,还没有开始移动
        int right = -1;
        int maxLength = 0;
        
        for (int left = 0; left < n; left++) {
            if (left != 0) {
                // 左指针向右移动一格,移除一个字符
                set.remove(s.charAt(left - 1));
            }
            
            // 不断移动右指针,直到遇到重复字符
            while (right + 1 < n && !set.contains(s.charAt(right + 1))) {
                set.add(s.charAt(right + 1));
                right++;
            }
            
            // 更新最大长度
            maxLength = Math.max(maxLength, right - left + 1);
        }
        
        return maxLength;
    }

    // 测试示例
    public static void main(String[] args) {
        LongestSubstring solution = new LongestSubstring();
        System.out.println(solution.lengthOfLongestSubstring("abcabcbb"));  // 输出:3
        System.out.println(solution.lengthOfLongestSubstring("bbbbb"));     // 输出:1
        System.out.println(solution.lengthOfLongestSubstring("pwwkew"));    // 输出:3
        System.out.println(solution.lengthOfLongestSubstring(""));          // 输出:0
    }
}
    

复杂度分析

  • 时间复杂度:O(n),其中n是字符串的长度。左指针和右指针分别最多移动n次。
  • 空间复杂度:O(min(m, n)),其中m是字符集的大小。在最坏情况下,整个字符串都没有重复字符,此时集合的大小为n。

关键要点

  • 滑动窗口技术的应用:通过调整左右指针维护一个有效的窗口
  • 哈希集合的使用:快速判断字符是否已存在于当前窗口中
  • 一次遍历即可完成计算,效率高,适合处理大规模字符串(题目中提示长度可达5×10^4)
  • 边界处理:当字符串为空时,直接返回0
相关推荐
普贤莲花6 分钟前
【2026年第18周---写于20260501】---舍得
程序人生·算法·leetcode
2zcode6 分钟前
基于深度学习的口腔疾病图像识别系统(UI界面+改进算法+数据集+训练代码)
人工智能·深度学习·算法
小龙报6 分钟前
【Coze-AI智能体平台】低代码省时高效:Coze 应用开发全流程指南
java·人工智能·python·深度学习·低代码·chatgpt·交互
陈随易11 分钟前
bun将会支持Bun.image,你怎么看?
前端·后端·程序员
Sarvartha15 分钟前
N 个字符串最长公共子序列(LCS)求解问题
数据结构·算法
一切皆是因缘际会15 分钟前
下一代 AI 架构:基于记忆演化与单向投影的安全智能系统
大数据·人工智能·深度学习·算法·安全·架构
念何架构之路20 分钟前
Go Web基础和Http演进
开发语言·后端·golang
falldeep22 分钟前
五分钟了解OpenClaw底层架构
人工智能·算法·机器学习·架构
m0_6294947322 分钟前
LeetCode 热题 100-----16.除了自身以外数组的乘积
数据结构·算法·leetcode
勿忘初心122123 分钟前
【Java实战】SpringBoot 集成 freemarker 导出 Word 模板
java·spring boot·freemarker·模板引擎·word导出·后端实战