LeetCode 3. Longest Substring Without Repeating Characters / 159. Longest Substring with At Most Two Distinct Characters / 340. Longest Substring with At Most K Distinct Characters

LeetCode 3. Longest Substring Without Repeating Characters

典型的Sliding Window的问题,维护一个不重复的最长字串的区间。每次加入一个新元素,并维护区间性质。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char,int> count;
        int max_len=0;
        int start=0;
        for (int i=0;i<s.size();++i){
            count[s[i]]++;
            while (count[s[i]]>1){
                --count[s[start++]];
            }
            max_len = max(max_len, i-start+1);
        }
        return max_len;
    }
};

 

Optimize

由于是ascii码,可以开一个256空间的数组来代替unordered_map。

可以记录每个字符最后一次出现的下标。如果 s[j] 在 [i,j) 中,即 hash[j]>=i 时,滑动窗口的起点 i 可以直接变成 hash[j]+1,而不用上述代码那样一个个找。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        vector<int> hash(256, -1);
        int res=0, start=0; //sliding window [start, i]
        for (int i=0;i<s.size();++i){
            if (hash[s[i]]>=start)
                start = hash[s[i]]+1;
            hash[s[i]] = i;
            res = max(res, i-start+1);
            //cout << start << ' ' << i << endl;
        }
        return res;
    }
};

 

159. Longest Substring with At Most Two Distinct Characters

由于是最多两个,我们需要记录window中出现不同字母的个数,而这个等于hashtable的size。

class Solution {
public:
    int lengthOfLongestSubstringTwoDistinct(string s) {
        unordered_map<char,int> count;
        int start=0, res=0;
        for (int end=0;end<s.size();++end){
            ++count[s[end]];
            while (count.size()>2){
                if (--count[s[start]]==0) count.erase(s[start]);
                ++start;
            }
            res = max(res, end-start+1);
        }
        return res;
    }
};

 

340. Longest Substring with At Most K Distinct Characters 

class Solution {
public:
    int lengthOfLongestSubstringKDistinct(string s, int k) {
        unordered_map<char,int> count;
        int start=0, res=0;
        for (int end=0;end<s.size();++end){
            ++count[s[end]];
            while (count.size()>k){
                if (--count[s[start]]==0) count.erase(s[start]);
                ++start;
            }
            res = max(res, end-start+1);
        }
        return res;
    }
};

 

 

posted @ 2018-05-17 10:48  約束の空  阅读(119)  评论(0)    收藏  举报