【LeerCode题目记录3】——无重复字符的最长子串

本文介绍了如何解决LeetCode中的无重复字符最长子串问题,首先尝试了双重for循环的思路,但因时间复杂度过高无法通过大数组测试。随后采用滑动窗口和while循环优化,虽然通过了题目但仅击败部分用户。最后提到官方答案使用了哈希集合来进一步提高效率。
摘要由CSDN通过智能技术生成

LeetCode第三题:无重复字符的最长子串

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

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

根据上一道题“找到字符串中所有的异位词”http://(https://social.citicpru.com.cn/bbs/#/thread?topicId=57)的经验, 这道题又是做字符串字母出现次数的判断,

所以可以想到需要使用的方法是滑窗滑窗滑窗!!!

一旦确定了这道题需要用到滑窗算法,那么figure out思路出来应该不难。

做这道题的时候,我第一次想到的双重for循环思路,也就是定义一个int i,再定义一个int j,分别作为数组s最左侧的指针和最右侧的指针组成滑窗,不断获取s的第i个元素到第j-1个元素组成的子串。

For循环思路:

第一层for循环i:i会遍历取从s的第0个元素一直到s的最后一个元素

第二层for循环j:在上层循环确定i的值后,j会遍历从s的第i+1个元素到s的最后一个元素,由此可以不断的枚举s的子串。

每当获取到子串,我们判定一下,在j遍历到下一个元素时获取的值是否已经在当前的子串中存在,如果是,结束本次j循环,直接让i遍历下一个值。(因为此时j就算继续往后走,子串中也已经存在至少两个相同的字符了。)如果否,则获取j遍历到下一个元素时产生的新的子串的长度。i和j的两层遍历都完成后,取最长的那个子串的长度。

这个思路比较简单,代码如下。

 

复制

对于一般的字符串,这个方法是完全OK的,但是根据前面几次被捶打的经验,在Leetcode上使用双重For循环这种复杂度为O(n²)的方法是100%无法通过提交的,因为LeetCode的测试用例一定会给你一个巨变态的超长数组,对于超长数组使用两层For循环的时间复杂度太高了,一定会超时的。所以双重For循环,对于LeetCode来说,就是不够优雅的暴力解法。

既然无法使用嵌套For循环,我们就要思考复杂度更低,效率更高的方式。如果for循环只能用一次来遍历外层,只能遍历出每个潜在子串首字符在s中的序号i(叫左指针好了),但内层我们仍然需要不断向后遍历一个右指针rpointer,才能形成一个起始为s的第i个元素,末尾为s的第rpointer-1个元素的子串,用于判定s的第rpointer个元素的值是否已存在于当前子串中。

不能用For循环,那么就用While循环好了,在循环是加上条件:rpointer的最大值不能超过s的长度,以及每次获取的s的第rpointer个元素的值不存在于上次循环产生的子串中,否则本轮对右指针的循环结束,让上层循环的左指针向右移动一位。

For循环+while循环的代码:

 

复制

再次取Leetcode提交,成了!

然而只击败了18%的用户。。。。。哎

 但是好歹通过了。

看了下官方答案,大致思路一致,但是使用了一个新的hashset来记录子串,以此来进一步提升效率。

晚安。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值