【力扣】无重复字符的最长子串,滑动窗口+哈希集合+优化

无重复字符的最长子串原题地址

方法一:滑动窗口

考虑用2个指针来维护子串,使得这条子串没有重复字符。

i和j表示下标,[i,j]表示子串,长度为j-i+1。我们可以用i遍历字符串的所有字符,对于每一个i,都尽可能地让j往右滑动,使得[i,j]为无重复字符的子串。此时,每一个i都有唯一对应的j,即j=r(i)。本题只需要求得j-i+1的最大值即可。

力扣的官方题解中给出了一个例子,可以很好地呈现这种思路。

j=r(i)这个函数是不减的。即对于任意i_1<i_2j_1=r(i_1)j_2=r(i_2),我们有j_1\leq j_2恒成立。这个结论可以直观地想象到,显然[i_1,j_1]没有重复字符,那么[i_2,j_1]自然也没有重复字符,所以j_2一定在j_1的右边。

那么问题就转换为,如何找到每个i对应的j呢?我们只需要维护一个哈希表,把当前[i,j]的所有字符都存进去。当i向右移动时,就移除最左边的字符;当j向右移动时,就添加最右边的字符。这样,我们可以时刻知道最右边的字符是否在[i,j]的范围内出现过,若出现重复字符,则此时的[i,j]就是当前i对应的无重复字符的最长子串。

注意,j必须初始化为-1,这是因为下标为0的字符也要存储进哈希表中。

// 方法一:滑动窗口+哈希集合set
class Solution {
public:int lengthOfLongestSubstring(string s) {unordered_set<char> us;int ans = 0;// 滑动窗口// i表示左边界,j表示右边界,即[i,j]int j = -1; // 右指针移动时要插入,设置成-1会插入第一个字符int n = s.size();for (int i = 0; i < n; ++i){// 左指针向右移动一格,要去掉左边的一个元素if (i){us.erase(s[i - 1]);}// 右指针向右移动一格,如果该字符没有重复,就插入while (j + 1 < n && !us.count(s[j + 1])){++j;us.insert(s[j]);}// 窗口长度为j-i+1ans = max(ans, j - i + 1);}return ans;}
};

方法二:双指针,对方法一的优化

方法一是固定左指针,让右指针动,最坏情况下,2个指针都要遍历一遍字符串。

我们可以考虑把每个字符当前最后一次出现的下标也存下来,这样左指针就不用一步一步动了,可以直接跳跃到某个位置。

具体的操作如下:仍然用i和j表示区间端点的坐标,这次采用(i,j]来表示子串,子串长度为j-i。使用j遍历字符串,对于每一个j,先在哈希表中查找当前字符s[j]有没有出现过,如果没有出现过,则当前子串(i,j]是合法的;若出现过,则需要更新i到当前字符最后一次出现的位置(如abcb,当j指向第2个b,i指向a前面,此时的子串abcb非法,需要把i更新为指向第1个b,此时对应的子串cb合法)。最后记得把当前字符的位置存进去。

更新i的位置时,应取(i和当前字符最后一次出现的下标m)的较大值,而不是直接取m。这是因为,若m<i,则更新后i反而向左走了,当前子串可能会出现重复字符,变为非法子串。

// 方法二:优化方法一,滑动窗口+哈希集合map
class Solution {
public:int lengthOfLongestSubstring(string s) {// 存储元素及其最后一次出现的下标unordered_map<char, int> um;int ans = 0;int n = s.size();int i = -1;for (int j = 0; j < n; ++j){// 如果该字符出现过,且在区间范围内,需要更新左端点auto it = um.find(s[j]);if (it != um.end()){//i = it->second; // err, 反例:abbai = max(i, it->second);}// 此时为右端点当前最后一次出现um[s[j]] = j;// 无重复区间长度为j-ians = max(ans, j - i);}return ans;}
};

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

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

相关文章

无人零售模式下,“IoT+鸿蒙”实现零代码搭建自动售货机监控大屏的可能性摸索

前言 新零售模式下&#xff0c;对loT的探索与应用还在继续。 而数字时代&#xff0c;数字化转型在零售行业中蔓延&#xff0c;而对于新的消费方式的探索&#xff0c;也在如火如荼的进行中。于是&#xff0c;一种新零售的形式——无人零售逐渐形成概念。 如果说&#xff0c;人…

【FPGA原型验证】FPGA 技术:芯片和工具-当今的 FPGA 器件技术

FPGA 技术&#xff1a;芯片和工具 本章的重点是基于FPGA的原型验证的现有技术&#xff0c;包括硬件和软件。它介绍了作为核心技术的 FPGA 的主要特点&#xff0c;以及与基于 FPGA 的原型开发相关的合成软件技术。以下各章将详细介绍如何使用这些技术。 首先&#xff0c;总体介绍…

部分意图分类【LLM+RAG】

在生成人工智能领域工作最有价值的事情之一就是发现新兴技术如何融入新的解决方案。 举个例子&#xff1a;在为北美顶级金融服务公司之一设计对话式人工智能助手时&#xff0c;WillowTree 的数据和人工智能研究团队 (DART) 发现&#xff0c;将意图分类与大型语言模型 (LLM) 结合…

071:vue中过滤器filters的使用方法(图文示例)

第071个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使用&#xff0c;computed&a…

linux centos 安装teleport

效果 安装 1.创建目录 mkdir -p /opt/teleport/data cd /opt/teleport/2.下载解压文件 wget https://tp4a.com/static/download/teleport-server-linux-x64-3.6.4-b3.tar.gz tar -xvf teleport-server-linux-x64-3.6.4-b3.tar.gz3.安装 cd /opt/teleport/teleport-server-l…

ShardingSphere 5.x 系列【7】元数据持久化

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 概述2. 单机模式2.1 H22.2 MySQL3. 集群模式3.1 ZooKeeper3.2 Nacos3.3 Cons…

Linux线程库封装

一 MyThread.hpp #pragma once #include<pthread.h> #include<iostream> #include<unistd.h> #include<string> #include<ctime>typedef void (*callback_t)(); static int num 1; //任务和线程绑定 class Thread {static void* Routine(void …

京东首页移动端-web实战

设置视口标签以及引入初始化样式 <link rel"stylesheet" href"./css/normalize.css"><link rel"stylesheet" href"./css/index.css"> body常用初始化样式 body {width: 100%;min-width: 320px;max-width: 640px;margin:…

leetcode1079:游戏玩法分析——求留存率

求留存率 题目描述题解 题目描述 表&#xff1a;Activity --------------------- | Column Name | Type | --------------------- | player_id | int | | device_id | int | | event_date | date | | games_played | int | --------------------- &#xff08;player_id&…

H2数据库

1.介绍 Java H2 是一个用 Java 编写的轻量级、开源的关系型数据库。它以其体积小、性能高、易于使用而闻名&#xff0c;常被用于开发和测试环境中&#xff0c;也适用于特定的生产环境。H2 数据库支持内存存储模式&#xff0c;这意味着数据可以直接存储在内存中&#xff0c;从而…

存内计算架构在通用视觉模型上的潜力应用

近年来&#xff0c;人工智能领域的通用视觉模型在自动驾驶、医疗图像分析、机器人视觉系统等场景中发挥了越来越重要的作用&#xff0c;它们通过模拟人类的视觉处理机制&#xff0c;有效地识别、理解和分析图像和视频数据。同时&#xff0c;新兴的存内计算架构显著优化了现有通…

SQLite database实现加密

注意&#xff1a;以下操作以VS2022为开发工具&#xff0c;以C#为开发语言。 数据加密原因 软件在使用的各个场景&#xff0c;很多都需要数据具有保密性&#xff0c;于是对于数据库就需要加密。特别是在某些特定领域或存储敏感数据尤其如此。 SQLite加密实现 SQLite加密有两种…