【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
相关推荐
期待のcode1 天前
MyBatisX插件
java·数据库·后端·mybatis·springboot
yaoh.wang1 天前
力扣(LeetCode) 13: 罗马数字转整数 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·跳槽
T1ssy1 天前
布隆过滤器:用概率换空间的奇妙数据结构
算法·哈希算法
醇氧1 天前
【Windows】优雅启动:解析一个 Java 服务的后台启动脚本
java·开发语言·windows
sunxunyong1 天前
doris运维命令
java·运维·数据库
菜鸟起航ing1 天前
Spring AI 全方位指南:从基础入门到高级实战
java·人工智能·spring
古城小栈1 天前
Docker 多阶段构建:Go_Java 镜像瘦身运动
java·docker·golang
hetao17338371 天前
2025-12-12~14 hetao1733837的刷题笔记
数据结构·c++·笔记·算法
华仔啊1 天前
这 10 个 MySQL 高级用法,让你的代码又快又好看
后端·mysql
MapGIS技术支持1 天前
MapGIS Objects Java计算一个三维点到平面的距离
java·开发语言·平面·制图·mapgis