0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

详解无重复字符的最长子串

算法与数据结构 来源:吴师兄学算法 作者:吴师兄 2022-09-06 11:56 次阅读

一、题目描述

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

示例 1:

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

示例 2:

输入:s="bbbbb"
输出:1
解释:因为无重复字符的最长子串是"b",所以其长度为 1。

示例 3:

输入:s="pwwkew"
输出:3
解释:因为无重复字符的最长子串是"wke",所以其长度为 3。
请注意,你的答案必须是子串的长度,"pwke"是一个子序列,不是子串。

提示:

0 <= s.length <= 5 * 10^4

s由英文字母、数字、符号和空格组成

二、题目解析

很经典的滑动窗口的题目。

具体操作如下:

1、定义需要维护的变量,对于此题来说,要求是最大长度,同时又涉及去重,因此需要一个哈希表。

2、定义窗口的首尾端 (start, end), 然后滑动窗口。

3、窗口的右端位置从 0 开始,可以一直移动到尾部。

4、如果哈希表中存储了即将加入滑动窗口的元素,那么需要不断的把窗口左边的元素移除窗口。

d82ffca6-2d92-11ed-ba43-dac502259ad0.pngd8437a56-2d92-11ed-ba43-dac502259ad0.png

5、此时,滑动窗口可以接纳新增元素。

d854e980-2d92-11ed-ba43-dac502259ad0.png

三、参考代码

1、Java 代码

//登录AlgoMooc官网获取更多算法图解
//https://www.algomooc.com
//作者:程序员吴师兄
//代码有看不懂的地方一定要私聊咨询吴师兄呀
//无重复字符的最长子串(LeetCode 3):https://leetcode.cn/problems/longest-substring-without-repeating-characters/
classSolution{
publicintlengthOfLongestSubstring(Strings){

//滑动窗口模板化解题,五步走策略

//【1、定义需要维护的变量】

//对于此题来说,要求是最大长度
intmaxLen=0;

//同时又涉及去重,因此需要一个哈希表
HashSethash=newHashSet();

//【2、定义窗口的首尾端(start,end),然后滑动窗口】

//窗口的左端位置从0开始
intstart=0;

//窗口的右端位置从0开始,可以一直移动到尾部
for(intend=0;end< s.length() ; end++ ){

            // 【3、更新需要维护的变量, 有的变量需要一个 if 语句来维护 (比如最大最小长度)】

            // 【4、如果题目的窗口长度可变: 这个时候一般涉及到窗口是否合法的问题】
            //  如果当前窗口不合法时, 用一个 while 去不断移动窗口左指针, 从而剔除非法元素直到窗口再次合法

            // 如果哈希表中存储了即将加入滑动窗口的元素
            while(hash.contains(s.charAt(end))){
                
                // 那么需要不断的把窗口左边的元素移除窗口

                // 把 s.charAt(start) 移除记录
                hash.remove(s.charAt(start));

                // 窗口左端向右移动
                start++;
            }

            // 此时,滑动窗口可以接纳 s.charAt(end)
            hash.add(s.charAt(end));

            // 维护变量 maxLen
            maxLen = Math.max(maxLen,end - start + 1);

        }

        // 【5、返回所需要的答案】
        return maxLen;

    }
}

2、C++ 代码

classSolution{
public:
intlengthOfLongestSubstring(strings){

//滑动窗口模板化解题,五步走策略

//【1、定义需要维护的变量】

//对于此题来说,要求是最大长度
intmaxLen=0;

//同时又涉及去重,因此需要一个哈希表
unordered_sethash;

//【2、定义窗口的首尾端(start,end),然后滑动窗口】

//窗口的左端位置从0开始
intstart=0;

//窗口的右端位置从0开始,可以一直移动到尾部
for(intend=0;end< s.length() ; end++ ){

            // 【3、更新需要维护的变量, 有的变量需要一个 if 语句来维护 (比如最大最小长度)】

            // 【4、如果题目的窗口长度可变: 这个时候一般涉及到窗口是否合法的问题】
            //  如果当前窗口不合法时, 用一个 while 去不断移动窗口左指针, 从而剔除非法元素直到窗口再次合法

            // 如果哈希表中存储了即将加入滑动窗口的元素
            while(hash.count(s[end])){
                
                // 那么需要不断的把窗口左边的元素移除窗口

                // 把 s.charAt(start) 移除记录
                hash.erase(s[start]);

                // 窗口左端向右移动
                start++;
            }

            // 此时,滑动窗口可以接纳 s.charAt(end)
            hash.insert(s[end]);

            // 维护变量 maxLen
            maxLen = max(maxLen,end - start + 1);

        }

        // 【5、返回所需要的答案】
        return maxLen;

    }
};

3、Python 代码

classSolution:
deflengthOfLongestSubstring(self,s:str)->int:
#滑动窗口模板化解题,五步走策略

#【1、定义需要维护的变量】

#对于此题来说,要求是最大长度
maxLen=0

#同时又涉及去重,因此需要一个哈希表
hash=set()

#【2、定义窗口的首尾端(start,end),然后滑动窗口】

#窗口的左端位置从0开始
start=0

#窗口的右端位置从0开始,可以一直移动到尾部
forendinrange(len(s)):

#【3、更新需要维护的变量,有的变量需要一个if语句来维护(比如最大最小长度)】

#【4、如果题目的窗口长度可变:这个时候一般涉及到窗口是否合法的问题】
#如果当前窗口不合法时,用一个while去不断移动窗口左指针,从而剔除非法元素直到窗口再次合法

#如果哈希表中存储了即将加入滑动窗口的元素
whiles[end]inhash:

#那么需要不断的把窗口左边的元素移除窗口

#把s.charAt(start)移除记录
hash.remove(s[start])

#窗口左端向右移动
start+=1

#此时,滑动窗口可以接纳s.charAt(end)
hash.add(s[end])

#维护变量maxLen
maxLen=max(maxLen,end-start+1)

#【5、返回所需要的答案】
returnmaxLen

四、复杂度分析

时间复杂度:O(N),其中 N是字符串的长度。左指针和右指针分别会遍历整个字符串一次。

空间复杂度:O(∣Σ∣),其中 Σ 表示字符集(即字符串中可以出现的字符),∣Σ∣ 表示字符集的大小。



审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    19

    文章

    2917

    浏览量

    103369
  • 字符串
    +关注

    关注

    1

    文章

    554

    浏览量

    20284
  • python
    +关注

    关注

    53

    文章

    4705

    浏览量

    83704

原文标题:LeetCode 3:无重复字符的最长子串

文章出处:【微信号:TheAlgorithm,微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    字符串写入数据库报错误的字符串

    在向表中姓名、性别、毕业院校中写入文字时会报错,错误为:错误的字符串值。输入数字能正常写入。错误vi为DB TOOLS insert Data.vi
    发表于 06-21 19:12

    使用PSOC UART与Nextion HMI进行通信,PSOC UART发送字符串不起作用的原因?

    =\"你好。 World\"\' 调试,字符串更新成功。 遗憾的是,使用 PSOC UART 发送相同字符串似乎不起作用。
    发表于 05-30 07:19

    STM32 USB的字符串描述符不能显示是哪里的问题?

    最近用STM32做了一个USB 的HID类设备,设备描述符中有指定厂商字符串索引、产品字符串索引、序列号索引。在获取字符串的代码部分也发现确实执行了,但是插上电脑后却没有我想要的字符串
    发表于 04-30 08:13

    STM32F407VE使用mbedOS开发SDIOBlockDevice时,inquiry字符串不能被发送如何解决?

    ); } 即端点类型是EP_TYPE_ISOC才发送ep->xfer_buff即上面inquiry字符串 而write函数里是EPBULK_IN发送,该端点类型是EP_TYPE_BULK型,也就是说inquiry字符串不能被发送. 这个问题如何解决,请大侠帮忙,
    发表于 04-22 07:53

    如何提取串口接收字符串数组里的某个字符串

    前几天搞了好久串口发送接收字符串的程序代码,终于搞出来了。还没高兴多久,新的问题又来了。我使用STM8S105K4的UART2口跟蓝牙模块通信的,我发送字符串指令给蓝牙后,蓝牙返回来了十几
    发表于 04-22 06:05

    PSoC™ 6 UART通信反复发送字符串是为什么?

    我正在尝试使用 UART 代码,但我修改了代码,一次又一次地发送字符串,而这次他只询问用户一次。 所以我想再三询问用户。 我还设置了一个 while (1) 循环,但仍然不起作用。 因此,请提供反复发送新字符串的 uart 示例。
    发表于 03-05 07:26

    USB字符串描述符里面的序列号字符串到底是什么东西?

    在设备描述符里面,有一个表示序列号字符串描述符的编号,请问这个序列号字符串的描述符是什么东西呢? 厂商字符串和设备字符串都能理解,而且在电脑的“设备与打印机”里面都找到了。但请问这个
    发表于 01-24 08:06

    LABVIEW用户输入的字符串,有办法实时接收吗?

    主要用在自动化测试上面,用户使用USB扫码枪,扫描结束 如果不用回车或者空白地方点下,字符串输入控件上面有扫描好的码,但是接收端接收不到,有什么办法解决吗
    发表于 01-12 11:14

    怎样进行字符串转数字?

    除了使用sprintf之外,自己写一个字符串转数字的程序应该怎样处理?sprintf的效率很低
    发表于 11-10 07:18

    关于字符串转换的问题求解

    我在串口上收到一个12位的字符串,比如是“1122334455EF”,怎么样转换成一个unsigned char的{0x110x220x330x440x550xEF}
    发表于 11-08 07:52

    在学51单片机,请问16进制字符串是啥意思?

    就是现在学EEpROM,,数值转换成16进制字符串啥意思,字符串不是Char型的吗,怎么有16进制呢,如题
    发表于 11-08 07:40

    c语言如何对比字符串是否相同?

    c语言如何对比字符串是否相同把一个字符串变量直接赋值给另一个变量怎么实现
    发表于 11-02 07:45

    怎么把int类型的数据转换成字符串?

    怎么把 int 类型的数据转换成字符串: 看项目有用 micrilib,itoa() 函数 和 sprintf() 能不能用呢?怎么用 比如把 int a=10;转换成字符串 charbuf[]=\"10\";
    发表于 11-01 08:27

    求助,如何把一字符串运算转化成定长字符串

    是128bit的,按4位二进制组合成一个十六进制,所以最后出来的十六进制字符串是32个,比如d3379f609e1aa88da2f50018d4fa218f。
    发表于 11-01 07:52

    IAR中UTF-8中文字符串不显示怎么解决?

    界面使用的是ucGUI原本使用GB2312编码的中字符串可以直接读取显示,字库也用FontCvt做了初始化的时候也添加了GUI_UC_SetEncodeutf8();函数 后面换成UTF-8的中文字符串
    发表于 10-07 07:11