解法一
双指针,left与right,各进行一次遍历
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int maxlen=0;
unordered_set<char> chars;
int right = 0;
for (int i = 0; i < s.size(); i++)
{
while(right<s.size()&& !chars.count(s[right])){
chars.insert(s[right]);
right++;
}
maxlen = max(maxlen,right-i);
if(right==s.size()) break;
chars.erase(s[i]);
}
return maxlen;
}
};
解法二
利用尾标映射,性能更好
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<int> map(128,-1);//map记录字符在当前子串上次出现的位置,全为-1
int len=0,start=0;//int map[128] = {-1}会出错;这只让第一个值为-1,其余的还是为0
for (int i = 0; i < s.size(); i++)
{
//此时还未进行本轮赋值,如果>start,表示s[i]赋值过,在本段中出现过
if(map[s[i]]>=start) start=map[s[i]]+1;
//map[s[i]]记录上次出现本字符的位置,+1更新start为新的子串起始位置
map[s[i]]=i;
len=max(len,i-start+1);
}
return len;
}
};