#题目描述:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
第一思路:以每一个元素作为待求最长子串的开头,进行遍历,时间复杂度N^3...........超出时间限制
class Solution {
public:
int getLengthOfSubString(int idx, string s){
// 哈希集合,记录每个字符是否出现过,常用函数:
// unordered_set::insert
// unordered_set::find
// unordered_set::erase
unordered_set<char> set;
int len = 1;
set.insert(s[idx]);
for(int i=idx+1; i<s.size(); i++){
if(set.find(s[i]) == set.end()){
set.insert(s[i]);
len++;
}else{
break;
}
}
return len;
}
int lengthOfLongestSubstring(string s) {
if (s.size()==0) return 0;
int len = 0;
for(int i=0; i<s.size(); i++){
int _len = getLengthOfSubString(i, s);
len = max(len, _len);
// cout<<s[i]<<" "<<_len<<endl;
}
return len;
}
划窗法:维护一个无重复字符的区间窗,从[0, 0]开始,每次右侧索引向右前进一步,判断新元素在之前是否出现过
如果有出现,则更新左侧索引,到上次出现的下一位,保证区间中始终无重复字符。更新窗口同时更新最大长度
时间复杂度 N^2
int lengthOfLongestSubstring(string s) {
if (s.empty()) return 0;
int left=0, right=1, len=1;
while(right < s.size()){
for(int i=left; i<right; i++){
if(s[i] == s[right]){
left = i+1;
break;
}
}
len = max(len, (right-left+1));
right++;
}
return len;
}
};