3. 无重复字符的最长字串

题目

给定一个字符串s,输出最长不含重复字符的子串的长度。
0 <= s.length <= 5 * 10^4
s由英文字母、数字、符号和空格组成
例如:
输入:s = "abcabcbb"
输出:3

思路

思路一 暴力求解

从第一个字符开始遍历,长度从0开始,统计每个字符开始时最长的不重复子串的长度,取最大值。

class Solution {  
public:  
    int lengthOfLongestSubstring(string s) {  
        int res = 0;//最大长度  
        int len = 0;  
        for (int i = 0; i < s.length() - res; ++i) {  
            len = 0;  
            unordered_set<char> cSet;  
            while ((i + len) < s.length()) {  
                if (cSet.find(s[i+len]) != cSet.end()) {  
                    break;  
                }else {  
                    cSet.insert(s[i+len]);  
                    ++len;  
                }  
            }  
            res = max(res, len);  
        }  
        return res;  
    }  
};

效果:
执行用时 880 ms 内存消耗 233.5 MB

思路二 滑动窗口

与暴力求解不同的是,发现重复字符后,应该从上一个不包含该字符处开始,而且部分字串已经确认不重复了
例如:s = "abcabcbb"
abc 下一个a发现重复了,则从b开始计,而且bca已经确认不含重复字符

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int first = 0, maxL = 0, len = 0;
        unordered_map<char, int> cMap;
        while (first + maxL < s.length()) {
            auto rep = cMap.find(s[first+len]);
            if (rep != cMap.end()) {  
                auto newFirst =  rep->second + 1;     
                while (first != newFirst) {
                    cMap.erase(s[first]);
                    --len;
                    ++first;
                }       
                cMap.insert(make_pair(s[first+len], first+len));
                ++len;
            }else {//未包含
                cMap.insert(make_pair(s[first+len], first+len));
                ++len;
                maxL = max(maxL, len);
            }
        }
        return maxL;
    }
};

效果:
执行用时 28 ms 内存消耗 10.4 MB

posted @ 2022-03-27 13:58  夏日花雪夜  阅读(62)  评论(0)    收藏  举报