问题:Given a string, find the length of the longest substring without repeating characters.
首先是题目的第三个例子:
Input: "pwwkew"
Output: 3
Explanation: The answer is"wke"
, with the length of 3. Note that the answer must be a substring, "pwke"
is a subsequence and not a substring.
查subsequence和substring的区别:substring必须是原字符串中连续的字符串,而subsequence可以不是。
所以对于例3,pw是连续的,但是第二个w和k是不连续的,所以p开头的substring最大长度只有2。所以计数的时候就是从前往后数,碰到一个出现过的计数就停止。
再看一个例子"pwwkew",从第一个字符开始数,第一轮数到第三个字符‘w’停止,然而第二轮从第三个字符‘w’开始数,数到最后一个字符‘w’停止,然后第三轮从第四个字符‘k’开始数,到结尾结束,最长substring为“wke”或“kew”长度为3。
我就用了最蠢的方法,像上面的例子一样一轮一轮的数,每一轮都将数过的数字存进vector,下一个数字存进来之前先判断一下当前这一轮存的数字里是否有这个数字,用的是vector的find()函数,如何发现这个数字已经在这一轮出现过,就用find()函数来找到这个已经出现过的数字的位置,那下一轮就从这个出现过的数的后面一位开始,如“abcaw”,第一轮数到a发现出现过,第二轮就从上一个a后面的b开始数。
然后有点麻烦的是得到已经出现过的数的位置,因为i是相对于string的第i项的,而find()返回的是一个InputIterator,所以首先要拿到那个已经出现过的数x在vector中的位置
i=(&*find(temp.begin(),temp.end(),s[i+1]) - &*temp.begin());
然后,要记录这是第几轮era,因为每增加一轮就相当于在string中跳过一个数,所以i+era,得到这个已经出现过的x在string中的位置,最后再i+1,得到x的后一位数,开始下一轮。
感觉自己这个方法很繁琐,不过看了这位大佬的博客,顺便复习了一下迭代器和指针的相关内容。
https://blog.youkuaiyun.com/gogoky/article/details/51206225
下面是完整代码
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int max = 0;
int i = 0;
int era = 0;
if(s.length() == 0)
return 0;
if(s.length() == 1)
return 1;
if(s.length() == 2){
if(s[0] == s[1]){
return 1;
}
else
return 2;
}
while(i<(s.length()-1)){
vector<char> temp;
int count = 1;
temp.push_back(s[i]);
while(find(temp.begin(),temp.end(),s[i+1])==temp.end() && i<(s.length()-1)){
temp.push_back(s[i+1]);
i ++;
count ++;
}
if(count > max){
max = count;
}
if(i<(s.length()-1)){
i=(&*find(temp.begin(),temp.end(),s[i+1]) - &*temp.begin())+1+era;
era ++;
}
}
return max;
}
};
最后看了一下大佬们的做法,有用256的数组来存所有字符的,这样用来判断是否出现过就很快。大佬们牛逼!