leetcode 3 无重复字符的最长子串

题目描述:

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

https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

 

思路1:暴力法(TLE)

枚举起始点,对起始点内的串检察是否存在重复字符,不存在则尝试更新最大子串长度。

 

思路2:优化的滑动窗口(这是在题解里看到的名字,我并不懂)

我们保存一个坐标值,在每次出现重复的时候更新为这个重复值的坐标+1。这样可以确定在这个坐标到当前的扫描位置之间的子串是没有重复的,再继续向后扫描即可。最大长度也是在出现重复时更新。

               

    

 

 

起初a就是没有重复的第一个字符。在扫描到第二个a时,rep记录改为第一个a的后一位,此时"bca“就是当前的最长子串值为3。一直这样扫描即可以得到最长的子串为”bacd“即为4。

注意,不要忘记扫描到最后一位的时候忘记更新,因为按我的重复时更新的思路,扫描结束是没有更新的。

可以这么做的思路很简单,在字符1到字符n,最大值我们已经更新为n-1或更大,所以1~n之间任一子串不可能超过这个值。而想要和外面的字符组成整体而不重复,由于是从左边扫描过来的,所以左边的情况已经考虑,右边当然只能从和字符n重复的字符i后一位开始i+1~n继续往后添字符。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        map<char,int> hash;//用hash存字符以及对应的下标
        int res=0;
        int rep=0;//用rep存重复值的后一位坐标。也是当前正在考虑的子串的起始位
        int len=s.length();
        for(int i=0;i<len;i++)
        {
            if(hash.count(s[i])&&hash[s[i]]-rep>=0)//表达式1判重,表达式2判断重复是不是发生在我们当前认定的子串中。如果是子串外当然不认为重复。
            {
                int cur=i-rep;//当前不重复的子串长度
                if(cur>res) res=cur;//更新最大值
                rep=hash[s[i]]+1;//更新重复坐标
            }
            hash[s[i]]=i;//子串外的字符坐标已经没有价值,更新为当前子串内这个字符的坐标。
        }
        if(len-rep>res) res=len-rep;//扫描到末尾更新一次
        return res;
    }
};

 

posted on 2019-09-20 17:01  夕影159  阅读(175)  评论(0)    收藏  举报

导航