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

算法练习题07:无重复字符的最长子串

我们可以使用 滑动窗口 的方法来解决这个问题。这是一种高效的算法,能在 O(n) 的时间复杂度内完成任务。以下是具体的解题思路:

1. 滑动窗口的概念

滑动窗口的想法是使用两个指针(通常称为左指针 i 和右指针 j)来表示一个窗口。这两个指针在字符串上滑动,以找到满足条件的子串。在这个问题中,我们的目标是找到最长的、没有重复字符的子串。

窗口的定义:窗口是由左指针 i 和右指针 j 所包围的子串 s[i:j],它包含 i 到 j-1 的字符。

窗口的移动:右指针 j 用于扩展窗口,左指针 i 用于缩小窗口。

2. 使用数据结构来检测重复字符

为了高效地检测一个字符是否已经在当前窗口中,我们使用一个 HashSet 数据结构。HashSet 允许我们在 O(1) 时间复杂度内判断一个字符是否存在,并且可以在 O(1) 时间内添加或移除字符。

3. 具体步骤
  1. 初始化

    • 定义一个 HashSet 来存储当前窗口内的字符。
    • 初始化两个指针 i 和 j,都指向字符串的开头(即 0)。
    • 初始化一个变量 maxLen 来记录最长无重复子串的长度。
  2. 遍历字符串

    • 使用 j 遍历整个字符串,将每个字符依次尝试添加到 HashSet 中。
    • 如果当前字符 s[j] 不在 HashSet 中:
      • 将其添加到 HashSet 中,表示扩展窗口。
      • 计算当前窗口的长度 j - i + 1,并更新 maxLen
    • 如果当前字符 s[j] 已经存在于 HashSet 中:
      • 说明遇到了重复字符,此时要通过移动左指针 i 来缩小窗口,直到移除重复的字符。
      • 移动左指针的过程中,同时从 HashSet 中移除对应的字符,直到可以将 s[j] 再次安全地添加到 HashSet 中。
  3. 更新结果

    • 每次右指针 j 向右移动时,计算当前窗口的长度,并更新 maxLen,以保证 maxLen 始终保持最长无重复子串的长度。
  4. 返回结果

    • 当右指针 j 遍历完整个字符串后,maxLen 就是最长无重复子串的长度。
class Solution {public int lengthOfLongestSubstring(String s) {HashSet<Character> set = new HashSet<>();int maxLen = 0;int i = 0, j = 0;int len = s.length();while (j < len) {if (!set.contains(s.charAt(j))) {set.add(s.charAt(j));j++;maxLen = Math.max(maxLen, j - i);} else {// 按顺序移除字符set.remove(s.charAt(i));i++;}}return maxLen;}
}

当右指针 j 遇到一个已经存在于 HashSet 中的字符时,我们需要移动左指针 i,从左侧开始逐个移除字符,直到移除重复的那个字符为止。这样可以确保 HashSet 中的字符总是唯一的。 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 临时性解决斐讯K3 路由器端口转发限制
  • GO Date数据处理
  • CSS-定位【看这一篇就够了】
  • 食堂线上预约点餐系统小程序的设计
  • 使用 FormCreate 渲染 Element Plus 表单
  • k8s1.23 部署Prometheus-Operator集群监控
  • 贪心算法---用最少数量的箭引爆气球
  • 【计算机网络】应用层HTTP协议
  • 数据赋能(193)——开发:数据服务——实施过程、应用特点
  • 142.环形链表二-力扣
  • Day 7:条件编译
  • 公务员面试(c语言)
  • ISO C++ 和 GNU C++ 的区别
  • MFC工控项目实例之十添加系统测试对话框
  • 苹果笔记本电脑能不能玩游戏?苹果电脑玩游戏咋样?
  • [ JavaScript ] 数据结构与算法 —— 链表
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • CentOS7 安装JDK
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • JavaScript 基本功--面试宝典
  • Javascript 原型链
  • k个最大的数及变种小结
  • Lsb图片隐写
  • mysql 数据库四种事务隔离级别
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • Python学习之路16-使用API
  • Rancher-k8s加速安装文档
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • 第2章 网络文档
  • 开发基于以太坊智能合约的DApp
  • 最简单的无缝轮播
  • 06-01 点餐小程序前台界面搭建
  • 1.Ext JS 建立web开发工程
  • ​iOS安全加固方法及实现
  • ​zookeeper集群配置与启动
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (1)Android开发优化---------UI优化
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (function(){})()的分步解析
  • (二)windows配置JDK环境
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (蓝桥杯每日一题)love
  • (算法)硬币问题
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .NET Core中的去虚
  • .Net MVC + EF搭建学生管理系统
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换