LeetCode 无重复字符的最长子串 打败100%的人
😀前言
LeetCode上的“无重复字符的最长子串”问题要求我们找到给定字符串中不包含重复字符的最长子串的长度。这个问题是一个典型的滑动窗口技巧的应用,需要有效地处理字符出现的情况来找到解决方案。
.
在本解决方案中,我们将探讨两种不同的算法实现来解决这个问题。首先,我们将使用基本方法来解决问题,然后进一步优化以获得更好的时间复杂度。
🏠个人主页:尘觉主页

🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉
在csdn获奖荣誉: 🏆csdn城市之星2名
💓Java全栈群星计划top前5
🤗 端午大礼包获得者
🥰阿里云专家博主
😉亚马逊DyamoDB结营
💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦😊
文章目录
- LeetCode 无重复字符的最长子串 打败100%的人
- 🤔无重复字符的最长子串
- 力扣官方题解
- 方法一:滑动窗口
- 思路和算法
- 优秀思路
- 自己思路
- 重点
- 总结
- 再优化一下
- 总结
- 😄总结
- 基本实现:
- 优化实现:
LeetCode 无重复字符的最长子串 打败100%的人
🤔无重复字符的最长子串

力扣官方题解
方法一:滑动窗口
思路和算法
我们先用一个例子考虑如何在较优的时间复杂度内通过本题。
我们不妨以示例一中的字符串 abcabcbb为例,找出从每一个字符开始的,不包含重复字符的最长子串,那么其中最长的那个字符串即为答案。对于示例一中的字符串,我们列举出这些结果,其中括号中表示选中的字符以及最长的字符串:

发现了什么?如果我们依次递增地枚举子串的起始位置,那么子串的结束位置也是递增的!这里的原因在于,假设我们选择字符串中的第 k 个字符作为起始位置,
并且得到了不包含重复字符的最长子串的结束位置为 rk 。那么当我们选择第 k+1k+1 个字符作为起始位置时,首先从 k+1到 rk的字符显然是不重复的,并且由于少了原本的第 k 个字符,我们可以尝试继续增大 rk ,直到右侧出现了重复字符为止。
这样一来,我们就可以使用「滑动窗口」来解决这个问题了:
-
我们使用两个指针表示字符串中的某个子串(或窗口)的左右边界,其中左指针代表着上文中「枚举子串的起始位置」,而右指针即为上文中的 rk ;
-
在每一步的操作中,我们会将左指针向右移动一格,表示 我们开始枚举下一个字符作为起始位置,然后我们可以不断地向右移动右指针,但需要保证这两个指针对应的子串中没有重复的字符。在移动结束后,这个子串就对应着 以左指针开始的,不包含重复字符的最长子串。我们记录下这个子串的长度;
-
在枚举结束后,我们找到的最长的子串的长度即为答案。
判断重复字符
在上面的流程中,我们还需要使用一种数据结构来判断 是否有重复的字符,常用的数据结构为哈希集合
在左指针向右移动的时候,我们从哈希集合中移除一个字符,在右指针向右移动的时候,我们往哈希集合中添加一个字符。
public int lengthOfLongestSubstring(String s) {// 哈希集合,记录每个字符是否出现过Set<Character> occ = new HashSet<Character>();int n = s.length();// 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动int rk = -1, ans = 0;for (int i = 0; i < n; ++i) {if (i != 0) {// 左指针向右移动一格,移除一个字符occ.remove(s.charAt(i - 1));}while (rk + 1 < n && !occ.contains(s.charAt(rk + 1))) {// 不断地移动右指针occ.add(s.charAt(rk + 1));++rk;}// 第 i 到 rk 个字符是一个极长的无重复字符子串ans = Math.max(ans, rk - i + 1);}return ans;}
优秀思路
这个打败100%

自己思路
首先因为字母表最大ASCLL为128所以我们就初始化128个空间并且假设全部没有出现为0,但是在数组中我们是0开头的所以什么设置为-1
其次我们设置 长度0 最大个数0 开始位置0
重点
我们开始循环 aabcd
i 代表我们是到那个字符了
首先我们读取每个字符的ASCLL值 赋值到index
然后我们开始计算 起始位置 如果这个字符出现过我们就更新起始实位置 last[index]上一次出现的位置 +1是 代表字符串内字符不能重复,所以要从上一次出现位置的下一个位置开始
如aabcd 第一个a 出现过一次 所以在 last[index] 的位置为 0 因为出现过一次了所以我们就从 第二个a 开始 就是 last[index]+1 以此类推
再是 我们比较 最大子串和 当前位置 i - 开始位置看谁最长 注意这个加1是代表次数 因为我们是从0开始 但是计数是从1开始 所以要+1
最后 我们记录这个字符在这个字符串中的位置 注意这个是字符串的位置是从0开始的
总结
要注意 计数 和在字符串 的位置 一个是从0 开始 一个是从 1开始 这就是为什么需要i - start + 1需要+1的原因
public int lengthOfLongestSubstring(String s) {// 记录字符上一次出现的位置int[] last = new int[128];for(int i = 0; i < 128; i++) {last[i] = -1;}int n = s.length();int res = 0;int start = 0; // 窗口开始位置for(int i =0 ; i < n; i++) {int index = s.charAt(i);start = Math.max(start, last[index] + 1);res = Math.max(res, i - start + 1);last[index] = i;}return res;}
再优化一下
大体逻辑是差不多的这里注意说一下区别
这里没有赋值是利用了java在初始化数组的时候是默认分配0
last[index] = i+1; 代表着这个字符出现的位置 比如 aabcd 第一个a 它的位置是 i+1=1次 到第二个a的时候就是 i=1
所以 start = Math.max(start, last[index])直接是从1开始 然后重新记录a的位置是 i+1=2 以此类推
注意这个是从 1开始的 不是0 包括后面 res也是从1开始 不是0
总结
要注意区分 统计 和 数组位置 以及 从1开始的位置
// 记录字符上一次出现的位置int[] last = new int[128];
// for(int i = 0; i < 128; i++) {
// last[i] = -1;
// }int n = s.length();int res = 0;int start = 0; // 窗口开始位置for(int i = 0; i < n; i++) {int index = s.charAt(i);start = Math.max(start, last[index]);res = Math.max(res, i + 1 - start );last[index] = i+1;}return res;
😄总结
基本实现:
-
初始化大小为128的数组last(表示ASCII字符)来跟踪每个字符上次出现的索引位置。将last中的所有元素初始化为-1,表示尚未见过任何字符。
-
从左到右遍历输入字符串s。
-
对于s中索引为i的字符,计算其ASCII值并将其存储在index变量中。
-
更新start变量,使其成为当前值和last[index] + 1中的较大者。这一步确保start表示当前不包含重复字符的子串的起始位置。
-
更新res变量,使其成为当前值和i + 1 - start中的较大者。这一计算找到了当前不包含重复字符的子串的长度,并与先前的最大长度进行比较。
-
更新last[index]为i + 1,记录字符在字符串中的最近位置。
-
重复步骤3-6,直到处理完整个字符串。
-
最终的res值将表示输入字符串s中不包含重复字符的最长子串的长度。
优化实现:
-
优化版本的解决方案消除了不必要的last数组初始化,并相应地调整了计算。还利用了Java默认使用零初始化数组的特性。
-
通过进行这些优化,代码变得更加简洁,并且在内存使用和代码简洁性方面都得到了改善。
-
这两种实现都提供了正确的答案,但优化版本在内存使用和代码简洁性方面都具有更高的效率。
这些实现为解决LeetCode上的“无重复字符的最长子串”问题提供了清晰而高效的方法,展示了滑动窗口技巧和字符出现情况跟踪的应用。
😁热门专栏推荐
想学习vue的可以看看这个
java基础合集
数据库合集
redis合集
nginx合集
linux合集
手写机制
微服务组件
spring
springMVC
mybits
等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持
🤔欢迎大家加入我的社区 尘觉社区
文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞
相关文章:
LeetCode 无重复字符的最长子串 打败100%的人
😀前言 LeetCode上的“无重复字符的最长子串”问题要求我们找到给定字符串中不包含重复字符的最长子串的长度。这个问题是一个典型的滑动窗口技巧的应用,需要有效地处理字符出现的情况来找到解决方案。 . 在本解决方案中,我们将探讨两种不同的…...
Spring Boot中通过maven进行多环境配置
上文 java Spring Boot将不同配置拆分入不同文件管理 中 我们说到了,多环境的多文件区分管理 说到多环境 其实不止我们 Spring Boot有 很多的东西都有 那么 这就有一个问题 如果 spring 和 maven 都配置了环境 而且他们配的不一样 那么 会用谁的呢? 此…...
python自动化Selenium的使用
python自动化Selenium的使用 Selenium是一个自动化测试框架,用于模拟和控制浏览器操作,支持多种编程语言。它可以模拟人类用户在浏览器上的操作(如点击、滚动、输入等),并检查网页内容和元素的属性。Selenium可用于对…...
大数据课程K13——Spark的距离度量相似度度量
文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Spark的距离度量和相似度度量; ⚪ 掌握Spark的欧氏距离; ⚪ 掌握Spark的曼哈顿距离; ⚪ 掌握Spark的切比雪夫距离; ⚪ 掌握Spark的最小二乘法; 一、距离度量和相似度度量 1. …...
Lambda表达式第四版
1、冗余的Runnbale代码 package com.lambda;public class Demo01Runnable {public static void main(String[] args) {RunnableImpl runnable new RunnableImpl();Thread thread new Thread(runnable);thread.start();//Lambda表达式} }class RunnableImpl implements Runnab…...
自定义类加载器
java中自定义类加载器,并将双亲委派改为逆向双亲委派 自定义类加载器JarLoader: package cn.ac.iscas.dmo.common.tools.core.classloader;import org.apache.commons.collections4.MapUtils;import java.io.*; import java.net.URL; import java.net.U…...
【Redis】Redis 的学习教程(七)之 SpringBoot 集成 Redis
在前几篇文章中,我们详细介绍了 Redis 的一些功能特性以及主流的 java 客户端 api 使用方法。 在当前流行的微服务以及分布式集群环境下,Redis 的使用场景可以说非常的广泛,能解决集群环境下系统中遇到的不少技术问题,在此列举几…...
Vlan和Trunk
文章目录 一、VLAN的定义与背景1. 传统以太网的问题(广播域)2. 用VLAN隔离广播域3. VLAN的优点与应用 二、VLAN的转发过程举例三、802.1Q标签:帧格式与作用四、VLAN工作原理交换机端口类型AccessTrunkHybrid PVID(Port VLAN ID&am…...
java 批量下载将多个文件(minio中存储)压缩成一个zip包
我的需求是将minio中存储的文件按照查询条件查询出来统一压成一个zip包然后下载下来。 思路:针对这个需求,其实可以有多个思路,不过也大同小异,一般都是后端返回流文件前端再处理下载,也有少数是压缩成zip包之后直接给…...
nnUNet v2数据准备及格式转换 (二)
如果你曾经使用过nnUNet V1,那你一定明白数据集的命名是有严格要求的,必须按照特定的格式来进行命名才能正常使用。 这一节的学习需要有数据,如果你有自己的数据,可以拿自己的数据来实验,如果没有,可以用十…...
ant-vue1.78版监听a-modal遮罩层的滚动事件
监听a-modal遮罩层的滚动事件 我们开发过程中经常有遇到监听页面滚动的事件需求,去做一些下拉加载或者是下拉分页的需求,我们直接在vue的生命周期中去绑定事件监听非常的方便,但如果是弹框的遮罩层的滚动监听呢?页面的监听完全是…...
MATLAB中residue函数用法
目录 语法 说明 示例 求解具有实根的部分分式展开式 展开具有复数根和同次分子及分母的分式 展开分子次数高于分母次数的分式 residue函数的功能是部分分式展开(部分分式分解)。 语法 [r,p,k] residue(b,a) [b,a] residue(r,p,k) 说明 [r,p…...
攻防世界-Caesar
原题 解题思路 没出现什么特殊字符,可能是个移位密码。凯撒密码加密解密。偏移12位就行。...
嵌入式开发-lin总线介绍 一.概述
1.1lin总线定义和历史 LIN总线(Local Interconnect Network)是一种基于UART/SCI(Universal Asynchronous Receiver-Transmitter/Serial Communication Interface)的低成本串行通信协议。它主要用于汽车、家电、办公设备等多种领域…...
羊城杯-2023-Crypto
文章目录 Danger_RSA题目描述:题目分析: Easy_3L题目描述:题目分析: XOR贯穿始终题目描述:题目分析: MCeorpkpleer题目描述:题目分析: SigninCrypto题目描述:题目分析&am…...
RabbitMQ快速上手及讲解
前言:在介绍RabbitMQ之前,我们先来看下面一个场景: 1.1.1.1 异步处理 场景说明: 用户注册后,需要发注册邮件和注册短信,传统的做法有两种 1.串行的方式 (1)串行方式:将注册信息写入数据库后&a…...
使用多线程std::thread发挥多核计算优势(解答)
使用多线程std::thread发挥多核计算优势(题目) 单核无能为力 如果我们的电脑只有一个核,那么我们没有什么更好的办法可以让我们的程序更快。 因为这个作业限制了你修改算法函数。你唯一能做的就是利用你电脑的多核。 使用多线程 由于我们…...
MySQL分页查询详解:优化大数据集的LIMIT和OFFSET
最近在工作中,我们遇到了一个需求,甲方要求直接从数据库导出一个业务模块中所有使用中的工单信息。为了实现这一目标,我编写了一条SQL查询语句,并请求DBA协助导出数据。尽管工单数量并不多,只有3000多条,但…...
解构赋值、函数默认值
暂时性死区,TDZ(Temporal Dead Zone) var x 1 {let x x//此处声明了x,但是没有对x赋值,相当于在赋值之前引用x,所以会造成报错console.log(x)//报错x is not defined,暂时性死区,…...
【已解决】Mybatis 实现 Group By 动态分组查询
🎉工作中遇到这样一个需求场景:实现一个统计查询,要求可以根据用户在前端界面筛选的字段进行动态地分组统计。也就是说,后端在实现分组查询的时候,Group By 的字段是不确定的,可能是一个字段、多个字段或者…...
nlp_structbert_sentence-similarity_chinese-large 赋能智能客服:基于Vue前端的问题相似度匹配实践
nlp_structbert_sentence-similarity_chinese-large 赋能智能客服:基于Vue前端的问题相似度匹配实践 你有没有遇到过这种情况?在某个网站的客服对话框里,输入一个问题,等了半天,要么是机器人答非所问,要么…...
Windows系统优化神器:Winhance中文版全面使用指南
Windows系统优化神器:Winhance中文版全面使用指南 【免费下载链接】Winhance-zh_CN A Chinese version of Winhance. C# application designed to optimize and customize your Windows experience. 项目地址: https://gitcode.com/gh_mirrors/wi/Winhance-zh_CN …...
DanKoe 视频笔记:个人成长:如何变得更加“不同意”(创造一个现实扭曲场)
在本节课中,我们将学习如何通过有意识地坚持自我、明确目标并有效沟通,来构建一个强大的“现实扭曲场”,从而更坚定地追求自己想要的生活,而非被动地迎合他人。 我们常常被教导要友善、随和,避免冲突。然而,…...
Phi-4-mini-reasoning作品集:自动将推理过程转化为教学级讲解语言
Phi-4-mini-reasoning作品集:自动将推理过程转化为教学级讲解语言 1. 模型简介 Phi-4-mini-reasoning是一个轻量级的开源文本生成模型,专注于将复杂推理过程转化为清晰易懂的教学语言。作为Phi-4模型家族的一员,它特别擅长处理需要逐步解释…...
5个维度解析LimeReport:Qt框架下的高效全能报表生成解决方案
5个维度解析LimeReport:Qt框架下的高效全能报表生成解决方案 【免费下载链接】LimeReport Report generator for Qt Framework 项目地址: https://gitcode.com/gh_mirrors/li/LimeReport 在企业级应用开发中,报表功能往往是连接数据与决策的关键纽…...
5G RedCap路由器如何选?关键特性解析与典型应用场景指南
1. 5G RedCap路由器选购的核心指标 第一次接触5G RedCap路由器时,我被参数表里密密麻麻的术语搞得头晕眼花。后来在工业现场实测了7款不同型号后,才发现真正影响使用体验的关键指标其实就这几个: 频段支持就像路由器的"语言能力"。…...
Ostrakon-VL像素UI设计细节:16色限定调色板与可访问性对比度达标
Ostrakon-VL像素UI设计细节:16色限定调色板与可访问性对比度达标 1. 项目背景与设计理念 1.1 从工业UI到像素艺术的转变 在零售与餐饮行业的AI应用场景中,传统工业级UI往往给人冰冷、复杂的印象。Ostrakon-VL扫描终端大胆采用8-bit复古像素风格&#…...
万象视界灵坛实战教程:广告Banner图受众情绪倾向语义解析实践
万象视界灵坛实战教程:广告Banner图受众情绪倾向语义解析实践 1. 平台介绍与核心能力 万象视界灵坛是一款基于OpenAI CLIP技术的高级多模态智能感知平台。它将复杂的图像语义分析过程转化为直观的交互体验,特别适合需要快速理解视觉内容情感倾向的营销…...
intv_ai_mk11效果实测:在中文长文本理解任务(>3000字技术文档)中摘要准确率与人工对比达92%
intv_ai_mk11效果实测:在中文长文本理解任务(>3000字技术文档)中摘要准确率与人工对比达92% 1. 引言:AI长文本理解的新突破 当我们面对动辄数千字的技术文档时,如何快速抓住核心内容一直是个难题。传统方法要么依…...
HarmonyOS6 半年磨一剑 - RcCheckbox 组件核心架构与类型系统设计
文章目录前言一、组件整体架构1.1 双组件协作设计1.2 文件结构1.3 装饰器分工二、类型系统深度解析2.1 值类型的宽泛设计2.2 选项配置接口2.3 形状与尺寸类型三、核心参数体系3.1 RcCheckbox 参数全览3.2 RcCheckboxGroup 扩展参数四、内部状态设计4.1 受控模式的双状态机制4.2…...
