勇闯力扣第三题(java)

在给定的字符串中找出不含重复元素的最长子串的长度,好像比前两题复杂了那么一些。
—————————————————————————
最简单能想到的办法就是:
从第一个字符开始遍历,遇到重复的元素时停止,记录长度,得到从第一个字符开始能够得到的不含重复元素的最大子串。
然后以此类推,可以得到从第二个,第三个等等。
感觉是个非常可靠的思路,不过两个循环嵌套,时间复杂度为n平方。
—————————————————————————
我们可以通过一个例子来看看时间都去哪了:
比如对如下这个字符串遍历
123451
第一次遍历的结果
(12345)1
从第一个字符开始得到的子串长度为5,除了这个信息之外,我们还可以得到一个信息:前五个字符不重复
然后第二次遍历的结果
1(23451)
有没有发现我们在第一次遍历时就已经确定的信息:前五个字符不重复在我们第二次遍历时又重新挨个确定了其中的四个也就是(2345),这样就显得非常呆了。
—————————————————————————
我们来考虑一个非常大胆的想法:
当我们第一次遍历结束时,会得到一个子串(12345)1
然后我们第二次遍历时,子串的起点确定是第二个字符也就是2,但我们遍历的起点可不可以直接从5开始呢?
把(2345)当做一个整体,这样就不会浪费之前遍历得到的信息。
需要两个指针来分别记录子串的首尾,“双指针”。
大致的代码应该是这样的,我随便写一下:

int maxl =0;
int n = s.length();
Set<Character> has = 
new HashSet<Character();
int rk =-1;
for(int i =0; i<n; ++i){
    //在第一次之后的遍历中,每次开始之前先从哈希集合中删掉上次循环开始的位置的字符
    if(i!=0){
         has. remove(s.charAt(i-1));
    }
    while(rk+1<n&& !has.contains(s.charAt(rk+1)){
        has. add(s.charAt(rk+1);
        ++rk;
    }
    max = Math. max(maxl,rk-i+1);
}
return maxl;

涉及的数据结构哈希我们在第一题就遇到过了,就不再浪费时间了。涉及到哈希的三个方法add() contains() remove()通过英文单词的意思就可以得到用法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值