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

008无重复字符的最长子串

无重复字符的最长子串

题目链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/?envType=study-plan-v2&envId=top-100-liked

我的解答:

public int lengthOfLongestSubstring(String s) { int length = s.length(); if(length==0){ return 0; } Map<Character,Integer> map = new HashMap<>(length);//维护每个字符最近出现的下标 int l=0, r=l+1, index=l; int ans=1; map.put(s.charAt(0),0); while(r<length){ while(r<length&&!map.containsKey(s.charAt(r))){ map.put(s.charAt(r),r); r++; } ans=Math.max(ans,r-l); if(r>=length){ break; } index=map.get(s.charAt(r))+1; while(l<index){ map.remove(s.charAt(l++)); } map.put(s.charAt(r),r); r++; } return ans; }

分析:代码的时间复杂度为O(n),空间复杂度为O(∣Σ∣),其中 Σ 表示字符集(即字符串中可以出现的字符)。我的思路是利用HashMap存储每次访问过的字符,并维护这个字符最近出现的位置;再利用两个指针l和r,指向未重复字符串的起始位置,r从l的下一个位置开始往右移动,直到遇到HashMap中重复的字符,更新答案,然后让l移动到重复字符最近出现的位置的后一个位置并同步删除HashMap中字符的记录,最后更新重复字符最近出现的记录即可。

看了官方题解后的解答:

public int lengthOfLongestSubstring(String s) { int length = s.length(); if(length==0){ return 0; } Set<Character> set = new HashSet<>(); int l,r; int ans=0; set.add(s.charAt(0)); for(l=0,r=l+1; r<=length; l++){ while(r<length&&!set.contains(s.charAt(r))){ set.add(s.charAt(r)); r++; } ans=Math.max(ans,r-l); if(r==length){ break; } set.remove(s.charAt(l)); } return ans; }

分析:

​ 1、代码的时间复杂度为O(n),空间复杂度为O(∣Σ∣),其中 Σ 表示字符集(即字符串中可以出现的字符)。

​ 2、采用滑动窗口。

​ 3、用HashSet记录字符。

​ 4、思路:根据每一个字符当作开头时最长的字符串的长度取最大值即为答案。且满足“当以索引为k的字符作为开头时,假设直到k+n才遇到重复的字符,那么以k+1开头的字符串直到k+n-1都不会遇到重复的字符”,根据这个条件,我们可以实现一直往后遍历而不会回退的情况,从而实现O(n)的时间复杂度解决问题。

​ 5、我的解答与官方解答的区别在于,我用hashSet不仅保存了字符,还维护了字符最近出现位置的索引,每一次遇到重复字符后我选择直接跳到这个字符最近出现的位置,而非将每一个元素都当作一次字符串的开头计算一遍。

​ 6、经过与官方题解比较发现,我才用的方法更符合双指针的特点。

总结

  • 本题主要是采用滑动窗口+哈希表解题,用哈希表避免重复,用滑动窗口维护以每一个元素作为开头的最长无重复子串。
http://www.jsqmd.com/news/736372/

相关文章:

  • Vibe Coding与算法作曲:从Sonic Pi到TidalCycles的代码音乐创作指南
  • 书匠策AI:论文降重与降AIGC的“魔法棒”,让学术创作更轻松!
  • 一分钟了解web3
  • 避坑指南:用AkShare批量下载沪深可转债分时数据时,你可能会遇到的3个常见错误及解决方法
  • 基于Webhook的代码变更通知工具:设计原理与实战部署指南
  • 3分钟高效搞定Figma中文界面:设计师必备的完整汉化解决方案
  • MATLAB斜杠命令框架:提升开发效率的原生交互方案
  • 企业级应用如何通过Taotoken实现稳定可靠的多模型API调用
  • 为AI编程助手定制规则集:从代码规范到智能引导的工程实践
  • 营销人自我成长路径:从小白到营销专家的学习指南
  • 为什么93%的Tidyverse项目在生产部署时崩溃?揭秘CRAN包锁定、环境隔离与RStudio Connect权限陷阱
  • M1/M2 Mac 上 VSCode 配置 OpenGL 环境,手把手搞定 GLFW 和 GLAD(含 CMake 配置)
  • Swoole多租户LLM会话管理全解析,深度解读连接复用率提升3.8倍与内存泄漏根因定位
  • 轻量级监控告警工具snag:配置驱动、无状态设计的实践指南
  • # Go 语言指针零基础入门详解
  • 3D智能体指令驱动与跨场景泛化技术解析
  • CSS如何控制多列布局的间距_通过column-gap设置css间隔
  • 本地优先AI知识库pm-pilot:一体化项目管理与智能笔记实践
  • 3步解锁iOS激活锁:applera1n开源工具深度解析与技术实战
  • VIOLA框架:低标注成本的视频上下文学习技术
  • 【LLM推理优化与部署工程⑦】买了8张GPU却只有3倍速度?钱都被这个东西吃掉了
  • 为什么92%的Laravel项目在AI集成后Q3运维成本翻倍?——Laravel Octane+Vector DB冷热分离计费策略全公开
  • 日志告警不再“狼来了”:用MCP 2026的语义理解引擎实现9类异常模式自动聚类(实测FP率降至0.8%)
  • Steam Achievement Manager:轻松管理Steam成就的终极解决方案
  • Grace与Ansys结合:高性能计算在汽车仿真中的突破
  • 【2026 年我 AI 编程最常用的 18 个提示词|从 Vibe Coding 到 Agentic Engineering 全覆盖】
  • 等保测评专家亲述:Docker 27容器镜像层签名失效=直接否决!金融级可信供应链构建的5个不可绕过的CA签发实践
  • CommandKenobi:一套跨AI编程助手的标准化工作流命令集
  • 避坑指南:YOLOv8+ByteTrack部署时,为什么你的目标ID总跳变?
  • PHP+AI不再“胶水式”开发(Laravel 12.1+专属方案):用自研AiPipeline组件替代硬编码调用,交付效率提升3.7倍(含Benchmark报告)