版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Murdock_C/article/details/49990815
这道题的题意很简单,其实就是求一个给定的字符串中最长的一段没有重复字符的子串。我刚开始是这样想的,设置两个下标,其中一个为找到不重复子串的开始位置,另外一个为不重复子串的终止位置,然后对字符串从头开始扫。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int maxLen = 0;
int start, end;
int b[26] = {0};
int i = 0;
start = end = 0;
while (i < s.length()){
if (!b[s[i]-'a']){
b[s[i]-'a'] = 1;
++i;
continue;
}
else{
end = i;
if (end-start > maxLen) maxLen = end - start;
start = i;
for (int j=0; j<26; ++j) b[j] = 0;
}
}
return maxLen;
}
};
然后TLE。后来看了给出的测试数据,发现给的不一定是在a~z这个范围内,还有其它字符串,于是又改成下面这个:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int maxLen = 0;
int start, end;
int b[256] = {0};
int i = 0;
start = end = 0;
while (i < s.length()){
if (!b[s[i]]){
b[s[i]] = 1;
++i;
continue;
}
else{
end = i;
if (end-start > maxLen) maxLen = end - start;
start = i;
for (int j=0; j<256; ++j) b[j] = 0;
}
}
return maxLen;
}
};
然后WA。后来又仔细看了一下代码,发现了一个问题:我求的子串都是没有交叉的。例如串abcdabcdabcd,我求得的子串只有三个:abcd 和abcd和abcd,也就是说,我每求得一个不重复子串,都是从这个不重复子串的后一位又重新开始求,其实是不对的,因为abcd是最长的不重复子串,但bcda也是最长的不重复子串,所以不对。
LeetCode上有给出一个参考答案,非常漂亮:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int maxLen = 0;
int b[256] = {0};
int i = 0, j = 0;
while (i < s.length()){
if (!b[s[i]]){
b[s[i]] = 1;
++i;
continue;
}
else{
if (i - j > maxLen) maxLen = i - j;
while (s[j] != s[i]){
b[s[j]] = 0;
++j;
}
++i;
++j;
}
}
if (s.length()-j > maxLen) maxLen = s.length() - j;
return maxLen;
}
};
它是在求得一个不重复子串之后,对这个不重复子串,从头开始扫,一直找到和子串末尾重复的那位开始,然后从他们下一个位置开始遍历,这样,就不会漏掉我们需要的最长的不重复子串。最后的if语句是防止如果我们找到最后,也没有找到重复的,有可能从j开始一直到字符串末尾都是一个不重复子串,所以需要判断一下。