【子串】3. 无重复的最长子串

3. 无重复的最长子串

难度:中等难度
力扣地址:https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/

在这里插入图片描述

题目看起来简单,刷起来有好几个坑,特此记录一下,解法比官网的更加简单,可读性强。时间复杂度与空间复杂度与官方一样。

问题描述

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

示例 1:

输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

示例 2:

输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。

示例 3:

输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

提示:

  • 0 <= s.length <= 5 * 1 0 4 10^4 104
  • s 由英文字母、数字、符号和空格组成。

问题分析

在这里插入图片描述

解决方法

结合示例 1,我做了一个详细的双指针移动 PPT 示意图。
在这里插入图片描述
在这里插入图片描述

解题代码

请小伙伴们结合上面的PPT进行理解,以下内容包括两种方法,第一种是基于哈希表,第二种使用 vector 替代哈希表,更快更节省资源(时间复杂度不变)

方法一:基于 unordered_map 记录历史 + 双指针一次遍历

class Solution {
public:int lengthOfLongestSubstring(string s) {// 用于记录每个字符最后一次出现的索引unordered_map<char, int> map;// 最终结果int result = 0;// 指针的开始位置,我们最终要求的无重复字符的最长子串的开始位置// 这个指针将会根据实际情况而移动,方向是一直向右int start = 0;// 一次遍历所有字符// 遍历过程中主要处理两个事情//   1. 移动 start 指针//   2. 计算现在已知的最长子串的长度for (int i = 0; i < s.length(); i++) {// 查找历史中该点auto tmp = map.find(s[i]);// 如果历史中存在数据,需要更新 start 的位置,表示新的最长子串的开始位置// 需要注意的是,更新后的start 必须越来越大,即向右边移动,避免 start 向左边移动if (tmp != map.end()) {start = max(tmp -> second + 1, start);}// 更新最后的结果,即最长子串的长度result = max(result, i - start + 1);// 写入/更新 s[i] 字符的索引map[s[i]] = i;}return result;}
};
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( ∑ ) O(\sum) O(),其中 ∑ \sum 表示字符集(即字符串中可以出现的字符),∣ ∑ \sum ∣ 表示字符集的大小。在本题中没有明确说明字符集,因此可以默认为所有 ASCII 码在 [0,128) 内的字符,即 ∣Σ∣=128。我们需要用到哈希集合来存储出现过的字符,而字符最多有 ∣ ∑ \sum ∣ 个,因此空间复杂度为 O(∣ ∑ \sum ∣)。

在这里插入图片描述

方法二:基于 vector 记录历史 + 双指针一次遍历

class Solution {
public:int lengthOfLongestSubstring(string s) {// 用于记录每个字符最后一次出现的索引vector<int> lastIndex(256, -1);// 最终结果int result = 0;// 指针的开始位置,我们最终要求的无重复字符的最长子串的开始位置int start = 0;// 一次遍历所有字符for (int end = 0; end < s.length(); end++) {// 更新 start 的位置if (lastIndex[s[end]] != -1) {start = max(lastIndex[s[end]] + 1, start);}// 更新最后的结果,即最长子串的长度result = max(result, end - start + 1);// 更新 s[end] 字符的索引lastIndex[s[end]] = end;}return result;}
};
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( ∑ ) O(\sum) O(),其中 ∑ \sum 表示字符集(即字符串中可以出现的字符),∣ ∑ \sum ∣ 表示字符集的大小。在本题中没有明确说明字符集,因此可以默认为所有 ASCII 码在 [0,128) 内的字符,即 ∣Σ∣=128。我们需要用到哈希集合来存储出现过的字符,而字符最多有 ∣ ∑ \sum ∣ 个,因此空间复杂度为 O(∣ ∑ \sum ∣)。
    在这里插入图片描述

总结

这道题目通过简单的双指针和哈希表的结合,可以高效地解决字符串中无重复字符的最长子串问题。这种方法的时间复杂度为O(n),因为每个字符在最坏情况下也只会被访问两次(一次作为结束字符,一次作为开始字符)。空间复杂度为O(1),因为哈希表的大小是固定的,最多为256个字符。

也正是基于这个原因,后面我们增加了使用 vector 提到哈希表,可以更加节省资源以及查找历史的时间。

Smileyan
2024.06.29 22:59

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/863236.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

51单片机第10步_数组

本章重点介绍如何访问数组。 #include <REG51.h> //包含头文件REG51.h,使能51内部寄存器; #include <string.h> //使能strcpy(); #include <stdio.h> //包含头文件stdio.h //_getkey();从串口读入一个字符; //putchar();向串口发送一个字节; //printf()…

[OtterCTF 2018]Play Time

还是这个程序 。。要找到游戏名字查看 进程 psscan pstree pslist 0x000000007d686b30 Rick And Morty 3820 2728 0x000000000b59a000 2018-08-04 19:32:55 UTC0000 0x000000007d7cb740 LunarMS.exe 708 2728 0x00000000731cb000 2018-08-04 19:27:39 UTC0000…

《昇思25天学习打卡营第12天 | 昇思MindSpore基于MindSpore的GPT2文本摘要》

12天 本节学习了基于MindSpore的GPT2文本摘要。 1.数据集加载与处理 1.1.数据集加载 1.2.数据预处理 2.模型构建 2.1构建GPT2ForSummarization模型 2.2动态学习率 3.模型训练 4.模型推理

支持纳管达梦数据库,命令存储支持对接Elasticsearch 8,JumpServer堡垒机v3.10.11 LTS版本发布

2024年6月24日&#xff0c;JumpServer开源堡垒机正式发布v3.10.11 LTS版本。JumpServer开源项目组将对v3.10 LTS版本提供长期的支持和优化&#xff0c;并定期迭代发布小版本。欢迎广大社区用户升级至v3.10 LTS最新版本&#xff0c;以获得更佳的使用体验。 在JumpServer v3.10.…

Redis主从复制、哨兵模式以及Cluster集群

一.主从复制 1.主从复制的概念 主从复制&#xff0c;是指将一台Redis服务器的数据&#xff0c;复制到其他的Redis服务器。前者称为主节点(Master)&#xff0c;后者称为从节点(Slave)&#xff1b;数据的复制是单向的&#xff0c;只能由主节点到从节点。默认情况下&#xff0c;…

More Effective C++ 35个改善编程与设计的有效方法笔记与心得 1

一. 基础议题 条款1&#xff1a;仔细区别 pointers 和 references ‌‌‌‌  这是一个常见的问题。指针&#xff08;pointers&#xff09;和引用&#xff08;references&#xff09;都是C面向对象编程中常用的概念&#xff0c;虽然他们在某些方面表现得很相似&#xff0c;但…

深入Symfony事件调度器:掌控应用程序的核心动力

&#x1f39a;️ 深入Symfony事件调度器&#xff1a;掌控应用程序的核心动力 &#x1f680; Symfony是一个高度灵活的PHP框架&#xff0c;以其组件化和可扩展性而闻名。在Symfony中&#xff0c;事件调度器&#xff08;Event Dispatcher&#xff09;是一个强大的工具&#xff0…

Github Page 使用手册(保姆级教程!)

搭建个人网站&#xff1f;没有服务器&#xff1f;那不如尝试一下 Github Page &#xff01; 最近我正好在搭建个人网站&#xff0c;于是就写一篇博客来详细介绍 Github Page 的使用、部署方式吧&#xff01; 一、进入 Github 访问&#xff1a;github.com 如果你没有 github…

Linux中彩色打印

看之前关注下公众号呗 第1部分&#xff1a;引言 1.1 Python在文本处理中的重要性 Python作为一种广泛使用的高级编程语言&#xff0c;以其简洁的语法和强大的功能在文本处理领域占有一席之地。无论是数据清洗、自动化脚本编写&#xff0c;还是复杂的文本分析&#xff0c;Py…

【第9章】MyBatis-Plus持久层接口之SimpleQuery

文章目录 前言一、使用步骤1.引入 SimpleQuery 工具类2.使用 SimpleQuery 进行查询 二、使用提示三、功能详解1. keyMap1.1 方法签名1.2 参数说明1.3 使用示例1.4 使用提示 2. map2.1 方法签名2.2 参数说明2.3 使用示例2.4 使用提示 3. group3.1 方法签名3.2 参数说明3.3 使用示…

RHCE四---web服务器的高级优化方案

一、Web服务器&#xff08;2&#xff09; 基于https协议的静态网站 概念解释 HTTPS&#xff08;全称&#xff1a;Hyper Text Transfer Protocol over Secure Socket Layer 或 Hypertext TransferProtocol Secure&#xff0c;超文本传输安全协议&#xff09;&#xff0c;是以…

【Android】保留elevation层级效果,舍弃阴影效果

关于elevation属性 elevation是高度&#xff0c;海拔的意思 该属性可以设置View在父容器中的层级&#xff0c;即z属性 当view的elevation高于其它view时&#xff0c;它将显示在最上方&#xff0c;并产生阴影效果 关闭阴影效果 view的高度阴影&#xff0c;通过outlineProvi…

【电磁学】-超表面

目录 一、定义与特性 二、工作原理 三、应用领域 四、研究进展与挑战 五、总结 一、定义与特性 定义&#xff1a; 超表面&#xff08;metasurface&#xff09;是一种厚度远小于波长的人工层状材料&#xff0c;通常由周期性或准周期性的亚波长单元结构组成。这些单元结构能…

amis做工具库 - Evalutor的使用 (字符串变量解析)

const { isEffectiveApi, parse, Evaluator } amisRequire("amis"); // console.log(window.amisRequire); //amisRequire是sdk方式引入挂载到window到。里面还有一些window document赋值&#xff0c;需要在浏览器环境下执行。 node端执行会报错&#xff0c;只能np…

huggingface镜像站

huggingface下载太慢&#xff0c;大模型文件太大。用huggingface_hub镜像。 pip install -U huggingface_hub pip install huggingface-cli export HF_ENDPOINThttps://hf-mirror.com huggingface-cli download --resume-download shenzhi-wang/Llama3-8B-Chinese-Chat --loc…

每天写java到期末考试--实验一---创建类---6.29

2、定义一个类Calculate,其中有一个main方法。 3、在main方法中,首先调用Scanner类,从键盘输入一个整数放到变量count中,count表示将要从键盘读入 的整数个数,然后调用循环语句从键盘读入count个整数,并保存到数组value中。 (1)将这count个整数求和,然后求出平均值。最后输出…

在Ubuntu 18.04.6 LTS 交叉编译生成Windows 11下的gdb 8.1.1

1. 安装mingw sudo apt-get install mingw-w64 2. 下载 gdb 8.1.1源码 https://ftp.gnu.org/gnu/gdb/gdb-8.1.1.tar.gz 解压命令 tar -xf gdb-8.1.1.tar.gz 进入目录,创建build目录: hq@hq:~/gdb-8.1.1/build$ 执行配置 ../confi

java实现图片添加水印

文章目录 前言一、工具类WatermarkUtil二、工具类介绍2.1 图片来源类型2.2 水印类型2.3 读取本地图片2.4 读取网络图片2.5 水印处理2.6 添加水印 三、测试添加水印总结 前言 给图片添加水印是一个很常见的需求&#xff0c;一般是用来防盗用。比如我们csdn上面写的文章中&#…

【鸿蒙学习笔记】@Extend装饰器:定义扩展组件样式

官方文档&#xff1a;Extend装饰器&#xff1a;定义扩展组件样式 [Q&A] Extend装饰器 作用 Extend用于扩展原生组件样式。 [Q&A] Extend装饰器 特点 &#xff11;・Extend仅支持在全局定义&#xff0c;不支持在组件内部定义。 &#xff12;・Extend支持封装指定组件的…

左耳听风_018_17_故障处理最佳实践应对故障

你好&#xff0c;我是陈浩网名猪耳朵house.我们多多少少呢都会经历一些线上的故障。 在我自己的职业生涯中呢就经历过很多的线上故障。 说实话&#xff0c;线上故障是我们技术人员成长中必须要经历的事儿。 从故障中呢&#xff0c;我们可以吸取到很多的教训&#xff0c;也能…