LeetCode刷题记录(二十七):无重复字符的最长子串


theme: smartblue

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第27天,点击查看活动详情

无重复字符的最长子串

image.png

题目解析

题目素材解析

根据题目的描述来看,就只给了一个字符串s。

并且这个字符串可能很长,长度最小为0,最大为50000。

并且字符串中可能存在英文、数字、符号、空格等元素。

我的解读

题目的预期结果是要在一个字符串中找出一个最长子串的长度,并且保证这个子串中的字符不重复。

我对本题的思路,其实是有两种方法。

其一,就是暴力美学的做法,利用双重循环来获取结果。但是很不幸,这种方法在我本地执行没有问题,就是慢;但竟然在LeetCode中执行超时,简直欲哭无泪。

其二,也是没有别的办法,为了运行通过,只能尝试其他方法。发现大家都在用滑动窗口的方式。

所以我就理了理思路,大概有以下几个重点需要突破一下。

一,在子串拼接中如何判断是否存在过某字符,可以使用Set集合,不需要字符出现的顺序,只需要判断是否存在某个元素即可。

二,理解滑动窗口的概念,妥善使用索引值。

滑动窗口的图例(从Ikaruga这个大佬题解中拿的)

image.png

解题思路

有了大概的思路,解题也就没那么难了。

特殊情况单独处理一下即可。

第一步,先声明一个结果值result,Set集合(存放字符)。

第二步,声明一个起始位置l。

第三步,根据素材字符串的长度来循环遍历。

第四步,判断是否在Set集合中存在,如果不存在,则证明此窗口往右延伸

第五步,如果存在,则需要窗口头部向尾部缩进,并且要缩进到当前值的下一个位置。

以此类推,得到最终结果。

这道题还是要先理解滑动窗口的概念,才能解出来。

代码

```java class Solution { /** * 滑动窗口 * 弃用split分隔方法,使用charAt方法提升效率。 * @param s * @return */ public int lengthOfLongestSubstring(String s) { //处理特殊情况 if(s.length() == 0){ return 0; } //声明一个结果值 int result = 0; //声明一个Set集合 Set set = new HashSet<>(); int l = 0; for (int r = 0; r < s.length(); r++) { Character si = s.charAt(r); if(set.contains(si)){ int z = l; while (true){ if(l < r && s.charAt(l++) == s.charAt(r)){ break; }else if(l >= r){ l = z; break; } } } if(r - l + 1 > result){ result = r - l + 1; } set.add(si); } return result; }

} ```

执行结果

一开始想多判断一下特殊情况,结果聪明反被聪明误,又提交错好几次。

image.png

Java代码本地执行

Java本地可调试代码,请参考github/Ijiran,可通过索引看到相应代码。

如下图所示:

image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ijiran

一杯咖啡太贵,一块糖就可以

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值