1. 程式人生 > >LeetCode (3) Longest Substring Without Repeating Characters

LeetCode (3) Longest Substring Without Repeating Characters

這道題的題意很簡單,其實就是求一個給定的字串中最長的一段沒有重複字元的子串。我剛開始是這樣想的,設定兩個下標,其中一個為找到不重複子串的開始位置,另外一個為不重複子串的終止位置,然後對字串從頭開始掃。

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開始一直到字串末尾都是一個不重複子串,所以需要判斷一下。