算法 - 无重复字符的最长子串(03)

news2024/11/25 0:44:03

原理:

定义左右两个指针,保证两个指针对应的子串中没有重复的字符,寻找并记录最长的子串长度。如果窗口满足条件,右指针向右滑动扩大窗口,更新最优值;如果窗口不满足条件,左指针向右缩小窗口。 (这里需要借助数据结构 -- 哈希集合,来判断是否有重复字符)

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目:

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1

示例:

输入:nums= [-1,0,3,5,9,12],target=9
输出: 4

 

提示: 

  1. 你可以假设 nums 中的所有元素是不重复的。
  2. n 将在 [1, 10000]之间。
  3. nums 的每个元素都将在 [-9999, 9999]之间。

 

思路1:滑动窗口

将左指针向右移动一格,表示我们开始枚举下一个字符作为起始位置,然后我们可以不断地向右移动右指针,但需要保证这两个指针对应的子串中没有重复的字符。在移动结束后,这个子串就对应着以左指针开始的,不包含重复字符的最长子串,我们记录下这个子串的长度。在枚举结束后,我们找到的最长的子串的长度即为答案。

在上面的流程中,我们还需要使用一种数据结构来判断是否有重复的字符,常用的数据结构为哈希集合(即 C++ 中的 std::unordered_set,Java 中的 HashSet,Python 中的 set, JavaScript 中的 Set)。

在左指针向右移动的时候,我们从哈希集合中移除一个字符,在右指针向右移动的时候,我们往哈希集合中添加一个字符。

答案:

① 方法1:暴力求解

逐个生成子字符串,看它是否不含有重复的字符 。

该方法虽然可以实现,但是不够优雅。 【208 ms         47.31 MB】

      var lengthOfLongestSubstring = function (s) {
        // 左右指针
        let left = (right = max = 0);
        let val = (endVal = "");
        let length = s.length;

        while (right < length) {
          endVal = s.charAt(right);
          if (val.indexOf(endVal) < 0) {
            val = val + endVal;
            // 右指针向右移动
            right++;
            if (right >= length) {
              max = max > val.length ? max : val.length;
            }
          } else {
            max = max > val.length ? max : val.length;
            left++;
            right = left + 1;
            val = s.charAt(left);
          }
        }
        return max;
      };
      console.log("答案", lengthOfLongestSubstring("abcabcbb")); // 3
      console.log("答案", lengthOfLongestSubstring("")); // 0
      console.log("答案", lengthOfLongestSubstring(" ")); // 1
      console.log("答案", lengthOfLongestSubstring("  ")); // 1
      console.log("答案", lengthOfLongestSubstring("aa")); // 1
      console.log("答案", lengthOfLongestSubstring("ab")); // 2
      console.log("答案", lengthOfLongestSubstring("pwwkew")); // 3

② 方法二:滑动窗口及优化

关键字:重复字符 --> 出现1次

模式识别1:一旦涉及出现次数,就需要用到散列表

构造子串,散列表存下标;
模式识别2:涉及子串,考虑滑动窗口 

 答案1:官方题解【96 ms      45.49 MB】

      var lengthOfLongestSubstring = function (s) {
        // 哈希集合,记录每个字符是否出现过
        const occ = new Set();
        const length = s.length;
        // 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
        let start = -1,
          res = 0;
        for (let i = 0; i < length; ++i) {
          if (i != 0) {
            // 左指针向右移动一格,移除一个字符
            occ.delete(s.charAt(i - 1));
          }
          while (start + 1 < length && !occ.has(s.charAt(start + 1))) {
            // 不断地移动右指针
            occ.add(s.charAt(start + 1));
            ++start;
          }
          // 第 i 到 start 个字符是一个极长的无重复字符子串
          res = Math.max(res, start - i + 1);
        }
        return res;
      };
      console.log("答案", lengthOfLongestSubstring("abcabcbb")); // 3
      console.log("答案", lengthOfLongestSubstring("")); // 0
      console.log("答案", lengthOfLongestSubstring(" ")); // 1
      console.log("答案", lengthOfLongestSubstring("  ")); // 1
      console.log("答案", lengthOfLongestSubstring("aa")); // 1
      console.log("答案", lengthOfLongestSubstring("ab")); // 2
      console.log("答案", lengthOfLongestSubstring("pwwkew")); // 3

答案2:个人【88 ms      45.73 MB】

      var lengthOfLongestSubstring = function (s) {
        // 定义左指针、右指针、长度、最大长度
        let left = (right = length = maxLength = 0)
        // 定义set集合
        let set = new Set()
        // 遍历字符串
        while (right < s.length) {
          if (!set.has(s[right])) {
            // 不存在相同字符,把当前字符添加到字符集中
            set.add(s[right])
            // 更新长度
            length++
            if (length > maxLength) {
              maxLength = length
            }
            // 右指针往右移动
            right++
          } else {
            // 删除字符集中的第一个字符
            set.delete(s[left])
            // 更新长度
            length--
            // 左指针往右移动
            left++
          }
        }
        return maxLength
      };

答案3:视频【68 ms       45.91 MB】

      var lengthOfLongestSubstring = function (s) {
        // 定义左指针、右指针、长度、最大长度
        let left = (right = length = maxLength = 0)
        // 定义set集合
        let set = new Set()
        // 遍历字符串
        while (right < s.length) {
          if (!set.has(s[right])) {
            // 不存在相同字符,把当前字符添加到字符集中
            set.add(s[right])
            // 更新长度
            length++
            if (length > maxLength) {
              maxLength = length
            }
            // 右指针往右移动
            right++
          } else {
            while (set.has(s[right])) {
              // 删除字符集中的第一个字符
              set.delete(s[left])
              // 更新长度
              length--
              // 左指针往右移动
              left++
            }
            set.add(s[right])
            length++
            right++
          }
        }
        return maxLength
      };

视频:

一道算法题理解滑动窗思想!【趣刷Leetcode】 No.3 无重复字符的最长子串_哔哩哔哩_bilibili

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

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

相关文章

打工人副业变现秘籍,某多/某手变现底层引擎-Stable Diffusion替换背景

在Stable Diffusion软件中,使用ControlNet+模型实现固定物体批量替换背景 出图的流程。 一、准备好图片 1.你需要准备好一些白底图或者透明底图用于训练模型。 2.你需要准备同样角度的其他背景色底图用于ControlNet勾线 3.注意检查你的图片尺寸,是否为1:1,…

L1-041:寻找250

题目描述 对方不想和你说话&#xff0c;并向你扔了一串数…… 而你必须从这一串数字中找到“250”这个高大上的感人数字。 输入格式&#xff1a; 输入在一行中给出不知道多少个绝对值不超过1000的整数&#xff0c;其中保证至少存在一个“250”。 输出格式&#xff1a; 在一行中…

移植Modelsim仿真工程

背景 上班在公司用的PC1生成并完整的进行了仿真&#xff0c;打包成zip&#xff0c;经过微信传输并在家里的PC2上打开想要继续进行仿真&#xff0c;需要如何处理呢&#xff1f; 环境 软件路径公司PC1Quartus II Prime Pro 21.4C:\intelfpga_pro\21.4\quartus\bin64\qpro.exeMo…

Nginx与keepalived高可用节点搭建实验

本文主要介绍了nginxkeepalived的部署实验&#xff0c;并简单说明了nginx的集中负载分担模式 简介&#xff1a; nginx可以通过反向代理功能对后端服务器实现负载均衡功能 keepalived 是一种高可用集群选举软件 keepalived架构 分为三个模块&#xff1a; 1、keepalived core …

基于java的医院住院管理系统的设计与实现论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对医院住院信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差…

SpringIOC之FullyQualifiedAnnotationBeanNameGenerator

博主介绍:✌全网粉丝5W+,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验✌ 博主作品:《Java项目案例》主要基于SpringBoot+MyBatis/MyBatis-plus+…

论文阅读:Lidar Annotation Is All You Need

目录 概要 Motivation 整体架构流程 技术细节 小结 概要 论文重点在探讨利用点云的地面分割任务作为标注&#xff0c;直接训练Camera的精细2D分割。在以往的地面分割任务中&#xff0c;利用Lidar来做地面分割是目前采用激光雷达方案进行自动驾驶的常见手段。来自Evocargo …

LeetCode Hot100 148.排序链表

题目&#xff1a; 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 class Solution {public ListNode sortList(ListNode head) {return sortList(head, null);}private ListNode sortList(ListNode head, ListNode tail) {if (head null)retur…

超详细 | 哈里斯鹰优化算法原理、实现及其改进与利用(Matlab/Python)

测试函数为F9 在MATLAB中执行程序结果如下&#xff1a; 在Python中执行程序结果如下&#xff1a; 哈里斯鹰优化算法(Harris Hawks Optimization , HHO)是 Heidari等[1]于2019年提出的一种新型元启发式算法&#xff0c;设计灵感来源于哈里斯鹰在捕食猎物过程中的合作行为以及突…

智能优化算法应用:基于原子搜索算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于原子搜索算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于原子搜索算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.原子搜索算法4.实验参数设定5.算法结果6.…

【算法刷题】Day16

文章目录 1. 不同路径题干&#xff1a;算法原理&#xff1a;代码&#xff1a; 2. 二分查找题干&#xff1a;算法原理&#xff1a;1、暴力解法 O(n)2、二分查找算法 朴素二分模版&#xff1a;代码&#xff1a; 1. 不同路径 原题链接 题干&#xff1a; 机器人只能向下和向右走&a…

网络协议介绍

一、网络层 1.网络层功能 ①定义了基于IP协议的逻辑地址 ②连接不同的媒介设备 ③在网络中选择最佳路径转发数据 2.使用版本 使用的IP协议版本 ipv4 ipv6 首部长度&#xff1a;IP头部的长度 3.标识符 确定数据的分片是否来自于同一个文件。 4.标志 代表数据过小&…

C# WPF上位机开发(树形控件在地图软件中的应用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们聊过图形软件的开发方法。实际上&#xff0c;对于绘制的图形&#xff0c;我们一般还会用树形控件管理一下。举个例子&#xff0c;一个地图…

聚观早报 |问界M9内饰爆料;滴滴乘车码上线北京

【聚观365】12月15日消息 问界M9内饰爆料 滴滴乘车码上线北京 小米汽车官方微博正式开通 网易市值超美团 华为nova 12 Ultra部分参数曝光 问界M9内饰爆料 据华为官方消息&#xff0c;12月26日将举办问界M9发布会。同时&#xff0c;余承东发布了一段问界M9的内饰视频&…

【STM32】STM32学习笔记-按键控制LED 光敏传感器控制蜂鸣器(08)

00. 目录 文章目录 00. 目录01. 按键控制LED接线图02. 按键控制LED程序示例03. 光敏传感器控制Buzzer接线图04. 有源蜂鸣器原理图05. 光敏传感器控制Buzzer示例06. 程序示例下载07. 附录 01. 按键控制LED接线图 02. 按键控制LED程序示例 led.h #ifndef __LED_H__ #define __L…

Qt 表格相关API

1.文本框 限制输入数据类型&#xff08;如仅英文&#xff09; QValidator* validator new QRegExpValidator(QRegExp("[a-zA-Z]"), lineText); // 创建正则表达式验证器lineText->setValidator(validator); // 将验证器设置给 QLineEdit QLineEdit&#xff1a;单…

岛屿数量介绍

在Java编程语言中&#xff0c;岛屿数量通常指的是在一个二维字符数组&#xff08;grid&#xff09;中&#xff0c;相邻的、值为1的格子数量。这个二维字符数组可能代表一个地图或一个二维平面&#xff0c;每个1代表一个岛屿或地形凸起&#xff0c;每个0代表一个海洋或平坦地区。…

HI3559AV100和FPGA 7K690T的PCIE接口调试记录-续

上文https://blog.csdn.net/fzktongyong/article/details/134963814?spm1001.2014.3001.5501 上一篇文中PCIE实测速度和理论计算有较大偏差&#xff0c;经过尝试后有所提升。 1、提升效果 1&#xff09;、RC写操作&#xff0c;实测速度817MB/s&#xff08;410407&…

JupyterNotebook VS JupyterLab 如果jupyter安装成功,点击jupyterlab即可进入lab环境

简介 JupyterNotebook 是一个款以网页为基础的交互计算环境&#xff0c;可以创建Jupyter的文档&#xff0c;支持多种语言&#xff0c;包括Python, Julia, R等等。一般来说&#xff0c;如果是使用R语言的话&#xff0c;使用Rstudio居多&#xff0c;使用Python的话&#xff0c;使…

第78讲:截取MySQL Binlog二进制日志中特定部分内容的技巧

文章目录 1.为什么要截取Binlog日志中的部分内容2.针对标识位截取Binlog日志中的部分数据2.1.以标识位号截取Binlog日志的方法2.2.截取Binlog日志中的部分数据2.3.模拟简单基于标识位的Binlog数据恢复 3.针对事件范围截取Binlog日志中的部分数据 1.为什么要截取Binlog日志中的部…