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