uacs2024

导航

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

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

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

 

滑动窗口模板

//外层循环扩展右边界,内层循环扩展左边界
for (int l = 0, r = 0 ; r < n ; r++) {
    //当前考虑的元素
    while (l <= r && check()) {//区间[left,right]不符合题意
        //扩展左边界
    }
    //区间[left,right]符合题意,统计相关信息
}

使用哈希表,用时16ms,内存12.3MB

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int size = s.size();
        if(size <= 1)  return size;
        int resMax = 0,lastNoRepeat = 0;
        unordered_map<char,int> letterAdded;
        for(int i = 0;i < size;i++){
            if(letterAdded[s[i]] == 1){
                int sizeT = letterAdded.size(); 
                resMax = max(resMax,sizeT);
                int j;////将当前s[i]的上一个相同的字符之前的所有字符都清楚,包括上一个相同的字符
                for(j = lastNoRepeat;s[j] != s[i];j++)  letterAdded.erase(s[j]);
                lastNoRepeat = j + 1;//更新最新的不重复字符串的开头
                continue;//因为本来就letterAdded[s[i]] == 1,所以直接下一轮循环
            }
            letterAdded[s[i]]++;
        }
        return resMax > letterAdded.size() ? resMax : letterAdded.size();
    }
};

上面的代码使用set  和  unordered_set

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int size = s.size();
        if(size <= 1)  return size;
        int resMax = 0,lastNoRepeat = 0;
        //unordered_set<char> letterAdded; //用时9ms,内存12.2MB
        set<char> letterAdded;//用时7ms,内存13.4MB
        for(int i = 0;i < size;i++){
            if(letterAdded.find(s[i]) != letterAdded.end()){
                int sizeT = letterAdded.size(); 
                resMax = max(resMax,sizeT);
                int j;////将当前s[i]的上一个相同的字符之前的所有字符都清楚,包括上一个相同的字符
                for(j = lastNoRepeat;s[j] != s[i];j++)  letterAdded.erase(s[j]);
                lastNoRepeat = j + 1;//更新最新的不重复字符串的开头
                continue;//因为本来就letterAdded[s[i]] == 1,所以直接下一轮循环
            }
            letterAdded.insert(s[i]);
        }
        return resMax > letterAdded.size() ? resMax : letterAdded.size();
    }
};

 不一样的写法,使用left和right两个指针

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int size = s.size();
        if(size <= 1)  return size;
        int resMax = 0,left = 0;
        unordered_set<char> letterAdded; //维护从 left 到 right 的字符
        for(int right = 0;right < size;right++){
            // 如果窗口内已经包含 s[right],那么再加入一个 s[right] 会导致窗口内有重复元素
            // 所以要在加入 s[right] 之前,先移出窗口内的 s[right]及其之前添加的字符
            while(letterAdded.contains(s[right])){
                letterAdded.erase(s[left]);//比如a b c d e c 1 2 3 4 5
                left++;
            }
            letterAdded.insert(s[right]);//最后再将当前的s[right]加入集合
            resMax = max(resMax , right - left + 1);
        }
        return resMax;
    } 
};

 

posted on 2024-12-06 17:19  ᶜʸᵃⁿ  阅读(9)  评论(0)    收藏  举报