最长不含重复字符的子字符串

 居然在剑指offer里刷到了这道题,记得虾皮一面的时候面试官就给了我这道题,当时思路有点混乱,没有做出来。今天刷到了之后,经过几番调试,终于做出来了。
 这道题做法其实很多,我一开始就想着用map存储,但是无法获取下标,所以进展不下去,后面还是两层循环弄了出来。第二层循环从后往前,只要遇到相同的,长度len直接等于**i-j**。代码如下:
public int lengthOfLongestSubstring(String s) {
        char[] chars = s.toCharArray();
        int len = 0;
        int maxLen = 0;

        int k=0;
        for(int i = 0;i < s.length();i++){
            for(int j = i-1;j>=k;j--){
                //从后往前遍历,遇到相同的元素,立马终止本层循环,长度=i-j
                if(chars[i]==chars[j]){
                    len = i-j-1;
                    k=j;
                    break;

                }

            }
            //如果没有相同的元素,长度就+1
            len++;
            //每次都和最大长度比较,大于它就重新赋值
            maxLen = maxLen>len?maxLen:len;

        }

        return maxLen;
    }

当然上面是我的比较粗暴的思路,还有更好的做法,这道题类似于求一个最长滑动窗口,用set去维护。代码如下:

public int lengthOfLongestSubstring1(String s) {
        int len = 0;
        Set<Character> set = new HashSet<>();

        for (int l=0,r=0;r<s.length();r++){
            char c = s.charAt(r);
            while (set.contains(c)){

                set.remove(s.charAt(l++));
            }

            set.add(c);
            len = Math.max(len,r-l+1);

        }
        return len;

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值