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; } };

浙公网安备 33010602011771号