问题描述:
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, the answer is "wke"
, with the length of 3. Note that the answer must be a substring, "pwke"
is a subsequenceand not a substring.
用一个哈希数据结构存储已经出现过的字符,考虑直接使用unordered_set(基于哈希的set)。很自然的想到Two Pointers,第一次实现的算法比较复杂,效率偏低,复杂度在O(n^2),提交后AC但是只超过了8%的submission。具体是一个大循环控制左边界,内部循环控制右边界,左边界每次递增,每次进入小循环首先清空set。代码:
int lengthOfLongestSubstring(string s) {
unordered_set<int> bag;
int i=0,j,maxL=0;
for(i=0;i<s.length();i++){
bag.clear();
for(j=i;j<s.length();j++){
if(bag.find(s[j])==bag.end())
bag.insert(s[j]);
else
break;
}
maxL=max(maxL,j-i);
}
return maxL;
}
第二次参考网上的题解,考虑到大循环左边界每次都递增的方式是造成效率低的主要原因。在右边界向右延伸的过程中每次出现set中已有字符时,让左边界向右走一步并在set中删除左边界刚走过的那个字符,只要左边界删掉的不是右边界的这个字符就一直删(移动左边界)。代码:
int lengthOfLongestSubstring(string s) {
unordered_set<int> bag;
int i=0,j=0,maxL=0;
while(j<s.length()){
if(bag.find(s[j])==bag.end()){
bag.insert(s[j++]);
maxL=max(maxL,(int)bag.size());
}
else{
bag.erase(s[i++]);
}
}
return maxL;
}