【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
相关推荐
松仔log1 小时前
JetPack——Paging3+Room
android·java·zoom
㳺三才人子6 小时前
初探 Flask
后端·python·flask·html
星栈独行6 小时前
我在 Rust 全栈项目里用 JWT 做无状态认证
开发语言·后端·rust·前端框架·开源·github·web
Lei活在当下6 小时前
先用起来,再理解,关于协程Coroutine应该知道的事
android·java·jvm
Java爱好狂.6 小时前
Java程序员体系化学习路线(2026最新版)
java·后端·java面试·java架构师·java程序员·java八股文·java学习路线
陈随易7 小时前
Redis 8.8发布,一定要更新
前端·后端·程序员
tongluowan0077 小时前
以ReentrantLock为例解释AQS的工作流程
java·模板方法模式·aqs·reentrantlock
装不满的克莱因瓶7 小时前
SpringBoot 如何将 lib 目录中jar包打包进最终的jar包里面
spring boot·后端·maven·jar·mvn
Raink老师7 小时前
【AI面试临阵磨枪-62】设计基于 RAG 的内部知识库问答平台(多租户、权限、文件上传、实时更新)
人工智能·面试·职场和发展
ltl8 小时前
Transformer 原论文实验结果:为什么 28.4 BLEU 足以改写路线图
后端