LeetCode (3) Longest Substring Without Repeating Characters
阿新 • • 發佈:2018-11-08
這道題的題意很簡單,其實就是求一個給定的字串中最長的一段沒有重複字元的子串。我剛開始是這樣想的,設定兩個下標,其中一個為找到不重複子串的開始位置,另外一個為不重複子串的終止位置,然後對字串從頭開始掃。
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開始一直到字串末尾都是一個不重複子串,所以需要判斷一下。