【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
相关推荐
魔都吴所谓几秒前
【python】快速实现pdf批量去除指定位置水印
java·python·pdf
Camel卡蒙2 分钟前
数据结构——字典树Trie(介绍、Java实现)
java·数据结构
Moment2 分钟前
NestJS 在 2025 年:对于后端开发者仍然值得吗 😕😕😕
前端·后端·github
kida_yuan3 分钟前
【Java】基于 Tabula 的 PDF 合并单元格内容提取
java·数据分析
Java水解9 分钟前
【Spring】Spring事务和事务传播机制
后端·spring
文心快码BaiduComate9 分钟前
文心快码实测Markdown排版工具开发
前端·后端·程序员
用户9047066835717 分钟前
java hutool 跟 JSONUtil 的关系
后端
渣哥17 分钟前
原文来自于:[https://zha-ge.cn/java/128](https://zha-ge.cn/java/128)
javascript·后端·面试
渣哥18 分钟前
项目写得再多也没用!Spring Bean 的核心概念要是没懂,迟早踩坑
javascript·后端·面试
白衣鸽子20 分钟前
MySQL 时间类型深度解析:精度、时区陷阱与版本兼容
数据库·后端·mysql