当前位置: 首页 > news >正文

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

目录

一、题目解析

示例 1:

示例 2:

示例 3:

二、算法原理

解法一:暴力枚举 + 哈希表(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))

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

  • 用两个指针leftright表示窗口左右边界。

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

滑动窗口的核心步骤:

  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循环写法(推荐!!!)

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循环写法

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)

http://www.rkmt.cn/news/1421110.html

相关文章:

  • Android Gradle - Gradle 依赖类型、Gradle 传递与去重、查看 APK 中的 versionCode 与 versionName、aapt 与 aapt2
  • 如何在Windows平台高效处理Electron应用的asar归档文件?WinAsar工具完整指南
  • 【诺奖得主领衔!高届数稳定EI检索】第十届能源、环境与材料科学国际学术会议(EEMS 2026)
  • 终极指南:3分钟用qmc-decoder轻松解锁QQ音乐加密格式
  • 比话降AI率售后怎么样?2026年知网AI率不达标全额退款实测
  • 新手必看:用Pikachu靶场通关10种SQL注入,从数字型到宽字节一篇搞定
  • MacBook上从零搭建国民技术N32G430开发环境:arm-gcc、VSCode、pyOCD保姆级配置
  • Java 泛型解析太痛苦?你可能需要一枚「蛋」
  • 南通黄金上门回收新趋势,福运来黄金回收用透明服务破解变现难题 - 黄金回收
  • Obsidian Tasks插件实战:如何与Calendar、Memos联动,打造你的GTD工作流
  • OpenCore Legacy Patcher终极指南:4步解锁老Mac完整性能
  • RK3568串口的配置首字节mark后续space的程序
  • GA/T 1400通知消息避坑指南:从设备ID生成到图片Base64编码的10个常见错误
  • Modbus Slave模拟器高级玩法:一台电脑如何虚拟出多个‘设备’?详解端口、站号与窗口的关系
  • 头戴式超声波三维定位跟随无人机系统-【2】
  • 基于NodeMCU与WS2812B的智能氛围灯DIY:从硬件连接到网页控制
  • 如何永久保存你的微信聊天记忆:WeChatMsg一站式数据管理指南
  • 2026年物流园重卡充电桩排名:充电效率、并发补能与平台开放性横向对比 - 科技焦点
  • RK3568+串口mark,space校验设置
  • MATLAB三元相图进阶玩法:用STernary类绘制带等高线、气泡图和凸包的数据可视化
  • 徐州黄金上门回收实测 福运来黄金回收领跑六强逐鹿谁更省心 - 黄金回收
  • 信道容量迭代算法:从理论公式到代码实现的完整指南
  • 基于Arduino与3D打印的DIY模拟赛车方向盘制作全攻略
  • 基于CircuitPython的交互式旋转木马:从硬件到代码的创客实践
  • 用PyTorch复现f-AnoGAN:一个工业缺陷检测的实战项目(附完整代码与数据集处理)
  • 给电赛萌新的保姆级教程:用CubeMX+Keil5从零点亮STM32F407(附避坑指南)
  • 秋衣面料革命,AI造出黑科技
  • 用C++刷题太枯燥?看我用Python优雅复现2023 GLPT天梯赛L2‘堆宝塔’与‘赛场安排’算法题
  • 在Claude Code中配置Taotoken作为替代API提供商解决访问限制
  • UE4植被动态效果避坑指南:从SimpleGrassWind撕裂到VertexColor绘制的完整解决方案