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

news2024/12/27 18:30:59

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.coloradmin.cn/o/1877580.html

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

相关文章

Json与Java类

简介 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。JSON数据由键值对构成&#xff0c;并以易于阅读的文本形式展现&#xff0c;支持数组、对象、字符串、数字、布尔值…

全国31省细分产品出口数据集(2002-2022年)

数据简介&#xff1a;整理全国31个省直辖市自治区按hs码分的22类细分产品的出口数据&#xff0c;只包含22类的细分&#xff0c;不包含更细的类目。可用来计算出口产品质量&#xff0c;出口产品技术复杂度等指标&#xff0c;数据区间为2002-2022年。 数据名称&#xff1a;31省细…

安卓开发自定义时间日期显示组件

安卓开发自定义时间日期显示组件 问题背景 实现时间和日期显示&#xff0c;左对齐和对齐两种效果&#xff0c;如下图所示&#xff1a; 问题分析 自定义view实现一般思路&#xff1a; &#xff08;1&#xff09;自定义一个View &#xff08;2&#xff09;编写values/attrs.…

【小学期】常用基于Swing的七个静态界面

示例1&#xff1a;基本的带按钮和标签的界面 import javax.swing.*; import java.awt.*;public class SimpleSwingApp1 {public static void main(String[] args) {JFrame frame new JFrame("Simple Swing App 1");frame.setDefaultCloseOperation(JFrame.EXIT_ON_C…

Qt之饼图(Pie Graph)

[TOC](Qt之饼图(Pie Graph)) 饼图名为Pie Graph&#xff0c;用于显示一个数据系列中各项的大小与各项总和的比例。本文基于QtCharts实现饼图的显示。 1.实现过程 1.1环境配置 &#xff08;1&#xff09;首先想要使用QtCharts模块&#xff0c;需要在安装qt时选择勾选安装QtCha…

ThreadPoolExecutor线程池创建线程

线程池介绍 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。提高响应速度。当任务到达时&#xff0c;任务可以不需要等到线程创建就能立即执行。提高线程的可管理性。线程是稀缺资源&#xff0c;如果无限制的创建&#xff0c;不仅会消耗系统资源&#…

一站式uniapp优质源码项目模版交易平台的崛起与影响

一、引言 随着信息技术的飞速发展&#xff0c;软件源码已成为推动行业进步的重要力量。源码的获取、交易和流通&#xff0c;对于开发者、企业以及项目团队而言&#xff0c;具有极其重要的意义。为满足市场对高质量源码资源的迫切需求&#xff0c;一站式uniapp优质源码项目模版…

在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

网盘挂载系统-知识资源系统-私域内容展示系统

系统介绍&#xff1a; 存储&#xff1a;一共支持约30款云盘存储&#xff0c;其中包括主流的&#xff08;百度网盘、阿里云盘、夸克云盘、迅雷云盘、蓝奏云、天翼云盘&#xff09;&#xff0c;部分展示 以及特别的&#xff08;一刻相册、对象存储、又拍云存储、SFTP、MEGA 网盘…

【旭日x3派】部署官方yolov5全流程

地平线旭日x3派部署yolov5--全流程 前言一、深度学习环境安装二、安装docker三、部署3.1、安装工具链镜像3.2、配置天工开物OpenExplorer工具包3.3、创建深度学习虚拟空间&#xff0c;安装依赖&#xff1a;3.4、下载yolov5项目源码并运行3.5、pytorch的pt模型文件转onnx3.6、最…

基于单片机技术的按键扫描电路分析

摘 要&#xff1a; 单片机应用技术被广泛应用于各种智能控制系统中&#xff0c;是电子信息类专业学生必修的一门专业课。在单片机端口信息输入模块中&#xff0c;按键是主要元器件之一&#xff0c;笔者主要介绍矩阵键盘的电路设计及控制程序编写&#xff0c;分析了单片机端口连…

C++:enum枚举共用体union

enum枚举 C继承C的枚举用法 (1)典型枚举类型定义&#xff0c;枚举变量定义和使用 (2)枚举类型中的枚举值常量不能和其他外部常量名称冲突&#xff1a; 举例1宏定义&#xff0c;举例2另一个枚举 // 定义一个名为Color的枚举类型 enum Color {RED, // 红色&#xff0c;默认值…

(单机版)神魔大陆|v0.51.0|冰火荣耀

前言 今天给大家带来一款单机游戏的架设&#xff1a;神魔大陆v0.51.0:冰火荣耀。 如今市面上的资源参差不齐&#xff0c;大部分的都不能运行&#xff0c;本人亲自测试&#xff0c;运行视频如下&#xff1a; (单机版)神魔大陆 下面我将详细的教程交给大家&#xff0c;请耐心阅…

学校消防设施设备管理系统

建立和落实校园消防安全管理责任制,做到消防安全工作有人专管,部门和岗位有人落实的日常管理&#xff0c;及时发现消防安全隐患,及时反映,及时处理,杜绝校园内消防安全隐患。 凡尔码平台搭建学校消防设施设备管理系统可以通过设备管理系统对消防器材设施基本信息、设施有效期、…

Webpack: 开发 PWA、Node、Electron 应用

概述 毋庸置疑&#xff0c;对前端开发者而言&#xff0c;当下正是一个日升月恒的美好时代&#xff01;在久远的过去&#xff0c;Web 页面的开发技术链条非常原始而粗糙&#xff0c;那时候的 JavaScript 更多用来点缀 Web 页面交互而不是用来构建一个完整的应用。直到 2009年5月…

Attention (注意力机制)

1. 背景&#xff1a; 字面的意思&#xff1a;给你一些东西(看见一个美女:).....)&#xff0c;你会注意什么&#xff1f; 大数据的时代下&#xff0c;有太多的数据&#xff0c;我们又该如何选择重要的数据呢&#xff1f; Attention 诞生了&#xff0c;但是又该如何去做呢(i.e., …

原子变量原理剖析

一、原子操作 原子操作保证指令以原子的方式执行&#xff0c;执行过程不被打断。先看一个实例&#xff0c;如下所示&#xff0c;如果thread_func_a和thread_func_b同时运行&#xff0c;执行完成后&#xff0c;i的值是多少&#xff1f; // test.c static int i 0;void thread…

MathType7.6永久破解激活码注册码 包含安装包下载

MathType是一款强大的数学公式编辑器&#xff0c;它能够帮助用户轻松编辑各种复杂的数学公式和符号。无论是学生、教师还是科研人员&#xff0c;MathType都能提供专业、精确的数学公式编辑服务。 在学习和工作中&#xff0c;我们常常会遇到需要编写数学公式的情况。然而&#x…

Excel+vue+java实现批量处理功能

需求背景: 产品创建流程比较复杂&#xff0c;有时候需要一次性创建多至10个&#xff0c;所以做了Excel维护产品信息&#xff0c;直接导入创建的功能。能极大提高效率。 简要概括实现&#xff1a; 一、参考单个创建&#xff0c;设计创建模板&#xff0c;表头对应填写字段名&…

Go使用Gin框架开发的Web程序部署在Linux时,无法绑定监听Ipv4端口

最近有写一部分go语言开发的程序&#xff0c;在部署程序时发现&#xff0c;程序在启动后并没有绑定ipv4的端口&#xff0c;而是直接监听绑定ipv6的端口。 当我用netstat -antup | grep 3601查找我的gin服务启动的端口占用情况的时候发现&#xff0c;我的服务直接绑定了tcp6 &a…