LeetCode (3) Longest Substring Without Repeating Characters

版权声明:本文为博主原创文章,未经博主允许不得转载。 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开始一直到字符串末尾都是一个不重复子串,所以需要判断一下。

猜你喜欢

转载自blog.csdn.net/Murdock_C/article/details/49990815