【LeetCode】滑动窗口妙解无重复字符的最长子串

news/2024/5/20 8:06:18 标签: leetcode, 算法, 滑动窗口

在这里插入图片描述

Problem: 3. 无重复字符的最长子串

文章目录

思路

首先我们来分析一下本题的思路

  • 如果读者有看过 长度最小的子数组 的话就可以清楚这个子串其实和子数组是一个道理,都是 连续的一段区间
  • 但是呢它们本质上还是存在一定区别的,这里说到是要我们去寻找不含有重复字符的【最长子串】, 读者可以看看下面我对这三个示例的分析
    • 对于示例1其最多长度只能为3
    • 对于示例2因为每一个都是一样的为b,那么最长子序列的长度即为1
    • 对于示例3的话这个大小也是一样为3

1.jpg

💬 所以到现在读者应该可以清楚题目到底是要我们做什么,接下去我们就具体地来讲解该如何去求解这个最长子串的长度

算法原理分析

马上我们通过两种解法来分析一下该如何去求解本题💡

暴力枚举 + 哈希表

首先要给大家介绍的肯定是暴力枚举,不过我们要通过【哈希表】来进行配合,如果对这个数据结构不太了解的话可以看看 一文带你快速入门哈希表

  • 不过呢,我们还是以双指针的模型来解题,右指针right用来遍历字符并将其放入哈希表中

2.jpg

  • 然后当这个right指针不断向后进行遍历的时候,将所遇到的字符全部放入哈希表中,最后当遇到有重复字符的时候,就停下来

3.jpg

  • 那么对于暴力解法来说的话,就会来到e这个位置,然后让right继续从这个位置开始向后进行移动,那么此时就可以清楚其会遍历到之前所碰到的那个重复的字符a;很明显,这是多此一举的做法

4.jpg

  • 因为我们所重复的是这个a,[d, e] 这个区间内并没有这个重复的元素a,所以呢这个right指针撑死了只能跑到这个第二次重复的位置

5.jpg

  • 所以我们在发现有重复元素需要进行第二次遍历的时候应该让这个left指针跑过这个重复元素才对,而且这个right指针不需要再回到当前left所在位置,而是直接从那个重复元素的位置开始向后遍历即可

6.jpg

滑动窗口

对于上面的这一种思想,我们就称之为【滑动窗口

  • 我们来捋一下这个滑动窗口的逻辑:

    1. 首先让leftright指针同时指向0的位置,遇到字符就往哈希表中放入字符
    2. 随着字符慢慢放入的时候,当窗口内出现了重复字符的时候,就需要从哈希表中删除该字符
    3. 接着去更新我们所需要的结果(最长子串的长度)即可。最后直到这个right超出边界之后,返回最终的那个结果
  • 以上就是本题使用滑动窗口进行求解的所有流程,读者可以根据这个思路顺利一遍逻辑,然后试着写写看代码

7.jpg

本题是我们滑动窗口的第二题了,如果有看过上一篇题解的读者应该可以知道对于滑动窗口而言,其代码是差不多的,读者在解决此类问题的时候不仅要知道我们为什么要利用【滑动窗口】去解决本题,而且还需要明白为什么使用【滑动窗口】来解决本题,这样大家在遇到类似题目的时候就可以很快地想到对应的解决策略✔

复杂度

  • 时间复杂度:

对于时间复杂度而言,读者在看了以下代码的时候,不要就认为两层循环就是 O ( n 2 ) O(n^2) O(n2),从开始到结束其实leftright指针各自遍历了一遍这个数组,所以最后的时间复杂度即为 O ( n ) O(n) O(n)

8.jpg

  • 空间复杂度:

没有在堆区上申请任何空间,所以空间复杂度为 O ( 1 ) O(1) O(1)

Code

以下是整体的代码展示

  • 为了照顾没学习过哈希表的同学,我使用数组来模拟的哈希表,其实数组的结构和哈希表挺类似的,也是下标和数组元素之间的映射关系,所以读者完全不用担心自己没有学习过哈希表
  • 如果你有认真分析过思路的话对下面的代码就会感觉到非常地清晰哦(๑•̀ㅂ•́)و✧
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n = s.size();
        int len = INT_MIN;
        int hash[128] = {0};    // 使用数组来模拟哈希表
        for(int left = 0, right = 0; right < n; ++right)
        {
            // 进窗口
            hash[s[right]]++;
            // 若发现有重复的字符出现
            while(hash[s[right]] > 1)
            {
                hash[s[left++]]--;      // 将字符从数组中移除
            }
            // 更新长度
            len = max(len, right - left + 1);
        }
        return len == INT_MIN ? 0 : len;
    }
};

在这里插入图片描述


http://www.niftyadmin.cn/n/5059351.html

相关文章

9.30号作业

1.消息队列实现进程间的通信 服务端 #include <myhead.h>#define ERR_MSG(msg) do{\fprintf(stderr,"__%d__:",__LINE__);\perror(msg);\ }while(0)typedef struct{ long msgtype; //消息类型char data[1024]; //消息正文 }Msg;#define SIZE sizeof(Msg)-s…

leetcode1610. 可见点的最大数目(java)

可见点的最大数目 题目描述滑动窗口 题目描述 难度 - 困难 leetcode1610. 可见点的最大数目 给你一个点数组 points 和一个表示角度的整数 angle &#xff0c;你的位置是 location &#xff0c;其中 location [posx, posy] 且 points[i] [xi, yi] 都表示 X-Y 平面上的整数坐标…

小黑子的java项目开发理解

小黑子的理解 一、基于Maven模板构建的三种常见Java项目——基于maven二、通常的java目录结构utils层 工具包model层&#xff08;pojo层&#xff09;exceptions层 报错包dao层&#xff08;mapper层&#xff09;[impl包—查询数据库]service层 定义接口 [impl—实现事务]control…

python二维码识别tesseract

window安装tesseract 下载路径&#xff1a; https://digi.bib.uni-mannheim.de/tesseract/ 选择 双击安装在D:\sore\teeseract-OCR后&#xff1a; 配置环境变量 配置环境变量Path&#xff1a;D:\sore\teeseract-OCR 配置语言包的环境变量TESSDATA_PREFIX&#xff1a; D:\s…

船舶单独安装的双频GNSS的PPP解算

最近我们在船舶上单独安装了一套双频GNSS&#xff0c;通过PPP解算用来验证GPS验潮的可能性。 GNSS观测文件是长格式&#xff1a;IGS000USA_R_20231920000_01D_01S_MO.rnx ​编辑​ 观测时间为2023年7月11日&#xff08;GPS时间&#xff09;。 从ftp://igs.ign.fr/pub/igs/pr…

Python爬虫获取百度图片+重命名+帧差法获取关键帧

&#xff08;清库存&#xff09; 获取图片 重命名 帧差法 爬虫获取图片文件重命名帧差法获取关键帧 爬虫获取图片 # 图片在当前目录下生成import requests import renum 0 numPicture 0 file List []def dowmloadPicture(html, keyword):global num# t 0pic_url re.fin…

Kafka收发消息核心参数详解

文章目录 1、从基础的客户端说起1.1、消息发送者主流程1.2、消息消费者主流程 2、从客户端属性来梳理客户端工作机制2.1、消费者分组消费机制 1、从基础的客户端说起 Kafka提供了非常简单的客户端API。只需要引入一个Maven依赖即可&#xff1a; <dependency><groupId…

图像处理: 马赛克艺术

马赛克 第一章 马赛克的历史渊源 1.1 马赛克 艺术中的一种表面装饰&#xff0c;由紧密排列的、通常颜色各异的小块材料&#xff08;如石头、矿物、玻璃、瓷砖或贝壳&#xff09;组成。与镶嵌不同的是&#xff0c;镶嵌是将要应用的部件放置在已挖空以容纳设计的表面中&#xff0…