10.滑动窗口解决:无重复字符的最长子串 | LeetCode 3 Java 题解

目录

一、题目解析

[示例 1:](#示例 1:)

[示例 2:](#示例 2:)

[示例 3:](#示例 3:)

二、算法原理

[解法一:暴力枚举 + 哈希表(O(n²))](#解法一:暴力枚举 + 哈希表(O(n²)))

解法二:滑动窗口(推荐!O(n))

滑动窗口的核心步骤:

三、编写代码(Java)

for循环写法(推荐!!!)

while循环写法

四、总结


OJ链接:无重复字符的最长子串

哈喽大家好!今天咱们来啃一道经典的算法题------无重复字符的最长子串。这道题在 LeetCode 上是第 3 题,难度中等,但绝对是必练的滑动窗口入门题!


一、题目解析

先看题目描述:

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

注意关键词:子串 (必须是连续的!)和无重复字符。

示例 1:

  • 输入:s = "abcabcbb"

  • 输出:3

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

示例 2:

  • 输入:s = "bbbbb"

  • 输出:1

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

示例 3:

  • 输入:s = "pwwkew"

  • 输出:3

  • 解释:因为无重复字符的最长子串是 "wke",所以长度为 3。(注意 "pwke"是子序列,不是子串!)

📌 小贴士:子串 vs 子数组 → 都是连续的一段!别被"子序列"带偏了!


二、算法原理

这道题有几种解法,我们重点讲两种:

解法一:暴力枚举 + 哈希表(O(n²))

  • 枚举所有子串,用哈希表判断是否有重复字符。

  • 时间复杂度高,不推荐,但可以作为理解题意的起点。

解法二:滑动窗口(推荐!O(n))

  • 利用"窗口"思想,维护一个++无重复字符的连续区间。++

  • 用两个指针 left和 right表示窗口左右边界。

  • 用一个数组(或哈希表)记录每个字符出现的次数。

滑动窗口的核心步骤:

  1. 初始化 :left = 0, right = 0

  2. 进窗口 :让 s[right]进入窗口 → hash[s[right]]++

  3. 判断 :如果 hash[s[right]] > 1→ 说明有重复!

  4. 出窗口 :从左边开始删,直到重复字符被移除 → hash[s[left++]]--

  5. 更新结果 :ret = Math.max(ret, right - left + 1)

  6. 移动右指针 :right++

关键点:窗口内始终是无重复字符的!一旦重复,就收缩左边界,直到恢复无重复状态。


三、编写代码(Java)

我整理了两种写法,for循环写法更推荐(结构清晰,易读),也保留了while循环写法,方便你对比学习。

for循环写法(推荐!!!)

java 复制代码
class Solution {
    public int lengthOfLongestSubstring(String ss) {
        // 先转换为字符数组
        char[] s = ss.toCharArray();

        // 数组模拟哈希表存储每个字符出现的次数
        // 也是滑动窗口需要维护的数据
        int hash[] = new int[128];

        int n = ss.length();
        int len = 0;
        for(int left = 0, right = 0; right < n; right++) {
            // 入窗口
            hash[s[right]]++;

            // 判断
            while(hash[s[right]] > 1) {
                // 出窗口
                hash[s[left++]]--;
            }

            // 更新结果
            len = Math.max(len, right - left + 1);
        }
        return len;
    }
}

while循环写法

java 复制代码
class Solution {
    public int lengthOfLongestSubstring(String ss) {
        char[] s = ss.toCharArray();

        int[] hash = new int[128];

        int left = 0, right = 0;
        int ret = 0;
        int n = ss.length();

        while (right < n) {
            // 入窗口
            hash[s[right]]++;

            // 判断
            while (hash[s[right]] > 1) {
                // 出窗口
                hash[s[left++]]--;
            }

            // 更新结果
            ret = Math.max(ret, right - left + 1);
            // 让下一个字符进入窗口
            right++;
        }
        return ret;
    }
}

四、总结

这道题是滑动窗口的经典入门题,核心是:

  • 用双指针维护窗口

  • 用数组/哈希表记录字符频次

  • 遇到重复就收缩左边界

  • 每次更新最大长度

时间复杂度:O(n)

空间复杂度:O(1)(因为字符集固定128)

相关推荐
陆卿之2 小时前
Java对接DeepSeek
java·开发语言·人工智能
庄园特聘拆椅狂魔2 小时前
Java 后端转全栈的第一课:从前端项目搭建到技术选
java·开发语言·前端
烽火聊员2 小时前
Android屏幕卡顿traces.txt拉取查看
android·java·android studio
Discipline10292 小时前
流水线运行是否正随时间变得更加集中?
算法
进击的明明2 小时前
TypeScript速通笔记(下)
前端·面试·typescript
lzhdim2 小时前
C#不为人知的10个魔法特性:资深开发者也会震惊的底层奥秘
java·前端·javascript·算法·c#
weixin_307779132 小时前
C++代码实现MATLAB中的pade函数功能
开发语言·c++·算法·matlab
smj2302_796826522 小时前
解决leetcode第4064题至多一次取反能被k整除的最长子数组II
python·算法·leetcode
AIGC小尼3 小时前
ACE-Step-1.5 本地 AI 音乐模型实战|text2music 歌词转人声,部署脚本、参数调优与排坑全记录
人工智能·算法·comfyui·ai漫剧
ProcessOn官方账号3 小时前
java IO操作 你快速认识IO的相关基本知识
java·开发语言