LeetCode刷题:无重复字符的最长子串 详解 【3/1000 第三题】

👤作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。
会一些的技术:数据分析、算法、SQL、大数据相关、python
作者专栏每日更新:
LeetCode解锁1000题: 打怪升级之旅

LeetCode解锁1000题: 打怪升级之旅https://blog.csdn.net/cciehl/category_12625714.html
python数据分析可视化:企业实战案例https://blog.csdn.net/cciehl/category_12615648.html
备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级

在字符串处理问题中,力扣(LeetCode)题库中的“无重复字符的最长子串”是一个经典的问题。这个问题的目标是从给定的字符串中找到最长的不含有重复字符的子串。

问题描述

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

示例:

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

解题思路-哈希集合

算法步骤

  1. 初始化:定义两个指针,一个哈希集合,和一个用于记录最长子串长度的变量。
  2. 滑动窗口:用两个指针表示字符串中的某个子串(或窗口),随着遍历的进行,调整指针和窗口的大小。
  3. 更新哈希集合:通过哈希集合来判断字符是否重复,并据此调整左指针。
  4. 更新最长长度:每次窗口滑动时,更新不含重复字符的最长子串的长度。

时间复杂度

算法的时间复杂度为 O(n),其中 n 是字符串的长度。在最坏的情况下,每个字符将被访问两次(由两个指针各一次)。

空间复杂度

空间复杂度为O(min(m,n)),其中 m 是字符集(字母表)的大小。这是因为哈希集合的大小取决于字符串的大小 n 和字符集的大小 m。

代码示例(Python) 

def length_of_longest_substring(s: str) -> int:char_set = set()left = max_length = 0for right in range(len(s)):while s[right] in char_set:char_set.remove(s[left])left += 1char_set.add(s[right])max_length = max(max_length, right - left + 1)return max_length# 测试代码
input_string = "abcabcbb"
print(length_of_longest_substring(input_string))

代码解释

  • 我们遍历输入字符串,使用两个指针 leftright 表示当前考虑的子串。
  • 我们使用一个集合 char_set 来存储当前子串中的字符。
  • 当我们碰到一个已经存在于集合中的字符时,我们就不断地移动左指针,并从集合中移除相应的字符,直到这个字符不再出现在集合中。
  • 每次我们都会更新最大长度 max_length

其他思路-字符集为数组

利用字符集为数组的方法特别适用于字符集大小固定且较小的情况,例如ASCII字符集。这种方法利用数组的索引来代表字符,数组的值来表示字符最后一次出现的位置。这样,我们可以在 O(1) 的时间内检查和更新每个字符的最后出现位置,从而在遍历字符串时快速判断当前字符是否重复,以及如何移动滑动窗口的起始位置。

代码示例

def length_of_longest_substring(s: str) -> int:# 初始化字符最后一次出现位置的数组,-1 表示字符尚未出现last_index = [-1] * 128  # ASCII 字符集大小为 128max_length = 0start = 0  # 滑动窗口的起始位置for i, char in enumerate(s):# 更新滑动窗口的起始位置# 如果当前字符之前出现过,则更新窗口起始位置为上一次出现位置 + 1if last_index[ord(char)] != -1:start = max(start, last_index[ord(char)] + 1)# 更新当前字符的最后出现位置last_index[ord(char)] = i# 计算当前无重复字符子串的长度,并更新最大长度max_length = max(max_length, i - start + 1)return max_length# 测试代码
input_string = "abcabcbb"
print(length_of_longest_substring(input_string))

这段代码首先初始化一个长度为128的数组last_index来存储每个ASCII字符最后一次出现的索引位置,初始值为-1表示字符未出现。随后遍历字符串,使用ord(char)获取字符的ASCII值作为索引,通过last_index数组来快速查找字符最后一次出现的位置,并据此更新滑动窗口的起始位置start。最终,通过比较每个字符对应的无重复字符子串长度来得到最大值。

算法对比

  1. 时间复杂度:这个方法仍然保持 O(n) 的时间复杂度,与基于哈希集合的滑动窗口方法相同。
  2. 空间复杂度:当字符集大小固定且较小时(比如ASCII字符集),这种方法的空间复杂度实际上是 O(1),相较于哈希集合方法(在最坏情况下可能接近 O(n),尽管实际使用中较少达到这个上限)更优。
  3. 操作复杂度:使用数组直接访问和更新字符的最后一次出现位置,操作更为直接和高效,特别是在字符集较小的情况下。

因此,如果你确定字符集的大小是固定和有限的,利用字符集为数组的方法在理论上是更优的选择,尤其是在空间复杂度上。然而,这种方法的优势主要体现在处理小字符集的字符串上,例如ASCII字符集。

但是,如果问题涉及到更大的字符集,比如Unicode字符集,哈希集合的方法可能更加灵活和通用,因为它不受字符编码范围的限制。同时,哈希集合方法的代码通常更简洁、易于理解和维护,特别是对于那些对特定编码方式不太熟悉的开发者。

 

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

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

相关文章

【THM】Active Reconnaissance(主动侦察)-初级渗透测试

介绍 在网络安全模块的第一个房间里,我们主要进行被动侦察。在第二个房间中,我们重点关注主动侦察以及与之相关的基本工具。我们学习使用网络浏览器来收集有关我们目标的更多信息。此外,我们讨论使用简单的工具(例如ping、traceroute、telnet和 )nc来收集有关网络、系统和…

centos7 安装 nginx

一、yum 方式安装 1.安装yum工具 sudo yum install yum-utils 2. 安装epel yum install epel-release 3.安装nginx: yum install nginx 4.查看版本 nginx -v 5.设置开机自启动 systemctl enable nginx nginx 常用命令: 1)启动nginx …

题目:给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。

题目:给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。 There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog co…

探讨在大数据体系中API的通信机制与工作原理

** 引言 关联阅读博客文章:深入解析大数据体系中的ETL工作原理及常见组件 关联阅读博客文章:深入理解HDFS工作原理:大数据存储和容错性机制解析 ** 在当今数字化时代,数据已经成为企业发展和决策的核心。随着数据规模的不断增长…

计算机组成原理实验(汉字编码实验)

(汉字编码实验) 海明校验码实验

Yarn 包管理器入门指南

一、Yarn 的由来 Yarn 是一个新的 JavaScript 包管理工具,由 Facebook 的工程师们开发,于 2016 年发布。Yarn 的诞生源于 NPM 在使用过程中遇到的一些痛点,如网络效率低下、缓存混乱、安装速度慢等问题。Yarn 秉承了 NPM 的部分理念,同时也做出了一些创新,以期提供更高效、安全…

每天五分钟计算机视觉:如何基于滑动窗口技术完成目标的检测?

汽车检测算法 现在我们想要构建一个汽车检测算法,我们希望输入到算法中一张图片,算法就可以帮助我们检测出这张图片中是否有汽车。 数据集 首先创建一个标签训练集,x是样本,y是标签。我们的训练集最好是被剪切过的图片,剪掉汽车以外的部分,使汽车居于中间位置,就是整张…

LeetCode-240. 搜索二维矩阵 II【数组 二分查找 分治 矩阵】

LeetCode-240. 搜索二维矩阵 II【数组 二分查找 分治 矩阵】 题目描述:解题思路一:从左下角或者右上角元素出发,来寻找target。解题思路二:右上角元素,代码解题思路三:暴力也能过解题思路四:二分…

家庭网络防御系统搭建-配置流量镜像到NDR系统

由于需要将家庭网络中的全部流量送到NDR分析系统进行分析,因此需要一个具备流量镜像功能的交换机或者路由器。在前面文章所提及的家庭网络架构中,需要一台交换机即可拷贝东西向流量以及南北向流量。当然如果家庭中的路由器或者其他设备具备交换机镜像功能…

基于单片机智能数字温度采集报警器系统设计

**单片机设计介绍,基于单片机智能数字温度采集报警器系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机智能数字温度采集报警器系统设计的核心目标是通过单片机实现温度的实时采集、显示以及超温报警…

多层感知机与DNN算法

多层感知机与DNN算法 神经网络与深度学习神经网络深度神经网络深度学习常见分类及应用 ensorFlow编程模型1 操作2 张量3 变量4 会话 3 TensorFlow 运行模式构建神经网络模型的工具指南1. 安装 TensorFlow2. 常见深度学习算法的库函数 其他机器学习算法:机器学习实战…

深度学习_NLP常用库报错问题解决

1、SpaCy can‘t find model ‘zh_core_web_sm‘. It doesn‘t seem to be a python package or a valid path to a data 或者 can‘t find model ‘en_core_web_sm‘. It doesn‘t seem to be a python package or a valid path to a data 安装最新的版本: en_…

C++项目——集群聊天服务器项目(七)Model层设计、注册业务实现

在前几节的研究中,我们已经实现网络层与业务层分离,本节实现数据层与业务层分离,降低各层之间的耦合性,同时实现用户注册业务。 网络层专注于处理网络通信与读写事件 业务层专注于处理读写事件到来时所需求的各项业务 数据层专…

【经典算法】LeetCode 20:有效的括号(Java/C/Python3实现含注释说明,Easy)

有效的括号 题目思路及实现方式一:栈(推荐)思路代码实现Java版本C版本(由于C语言需要自己实现栈较为繁琐,此处使用C)Python3版本 复杂度分析 方式二:递归法思路代码实现Java版本C语言版本Python3版本 复杂度分析 总结相…

UE5 SQLite笔记

开发环境: 系统:Windows 10 64 bit 引擎:Unreal Engine 5.1.1 IDE:JetBrains Rider 2023.2.1 语言:C 工具:DB Browser for SQLite SQLite数据类型: //INTEGER TEXT BLOB REAL NUMERIC/*integer…

Docker 设置redis 集群

安装Docker: 首先确保你的系统上已经安装了Docker和Docker Compose。你可以根据官方文档进行安装:https://docs.docker.com/get-docker/ 编写Docker Compose文件: 创建一个Docker Compose文件(例如docker-compose.yml&#xff09…

关于OpenFeign的返回类型包装问题

在一天夜里。我在使用feign的调用时,突然出现了一点点问题。 就是对于feign类型的包装问题。产生了疑问。 在后来,也就是今天。在网上取取经。看到了一个答案。说:feign的调用会有一个编码器和解码器。 使用feign的解码器。他的原理也很简…

NoSQL之Redis配置

文章目录 NoSQL之Redis配置一、关系数据库和非关系数据库1、关系型数据库2、非关系型数据库3、非关系型数据库产生背景4、关系型数据库和非关系型数据库的区别4.1 数据存储方式不同4.2 扩展方式不同4.3 对事务性的支持不同 5、总结5.1 关系型数据库5.2 非关系型数据库 二、Redi…

Linux中关于文件管理方面常用命令行介绍

Linux操作系统以其高效的文件管理系统而著称,它提供了丰富的命令行工具来管理文件和目录。这些命令行工具使得用户可以轻松地创建、复制、移动、删除和查找文件,以及修改文件的权限和所有权。下面将介绍一些Linux中关于文件管理方面常用的命令行工具。 …

Linux中关于驱动方面常用命令行介绍

Linux中关于驱动方面的常用命令行涵盖了多个方面,包括驱动加载与卸载、设备查看与管理、驱动信息查询以及驱动开发等。以下是一些常用的命令行工具及其功能介绍: 驱动加载与卸载: insmod:加载指定内核模块(驱动&#x…