3. Longest Substring Without Repeating Characters

Sneezry發表於2015-03-27

Difficulty: Medium

Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.

找出不包含重複字母的最長子字串長度

【分析】

最直接的想法就是找出所有不包含重複字母的子字串,然後再找出最長子字串的長度。這樣的時間複雜度為O(N^2),速度會慢很多。其實我們不必找出所有的子字串,比如對於abcdbec來說,它的全部不包含重複字母的子字串為

a
ab
abc
...
b
bc
bcd
....

但是可以看出,如果abcd是目前找到的最長的子字串,我們根本沒有必要返回頭再去判斷bcd,即排除子字串的子字串。

那麼我們的思路就是,從字串的起始位置開始判斷,依次向後包含一個字母,同時記錄當前子字串的長度,如果找到了重複的字母,則找出當前子字串中重複字母的位置,並從此位置的後面繼續找子字串

abcdbec // 從字串的起始位置開始判斷
^
...
abcdbec // 找到了重複的字母
^   ^
abcdbec // 找出當前子字串中重複字母的位置
 ^
...
abcdaec // 從此位置的後面繼續找子字串
 ^   ^
...

同時判斷當前子字串是否是最長的,如果是最長的,則更新最長數值。

在實際程式設計中,我將變數i定義為當前子字串的結尾的下一個位置,比如如果我們當前的子字串為ab,那麼i的位置是c,並判斷c是否包含在ab中,如果不包含就將c加進去,並且當前子字串長度currentLen加1

abcdaec
--^

那麼當前子字串為s.substr(i-currentLen,currentLen)i位置字母出現在當前子字元的s.substr(i-currentLen,currentLen).indexOf(s.substr(i,1))上,令這個位置為repeat

repeat = s.substr(i-currentLen,currentLen).indexOf(s.substr(i,1));

如果repeat的值是-1就代表不包含,我們字串長度加1

if(repeat === -1){
    currentLen++;
}

否則我們將當前子字串的其實位置調到出現重複字母位置的後面,這裡改變子字串長度即可

else{
    currentLen -= repeat;
}

如果當前子字串長度比最大值maxLen還大,就更新最大值

if(maxLen<currentLen){
    maxLen = currentLen;
}

根據前面定義,i的值是從1開始的,所以

for(i=1; i<len; i++){
    ...
}

對於長度是1的字串,這個迴圈不會執行,所以我們應該給maxLen一個初始值1

maxLen=1;

同樣也應該給currentLen一個初始值1

currentLen=1;

對於空字串,直接返回0即可

if(s===''){
    return 0;
}

最終完整的程式碼為

/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstring = function(s) {
    if(s===''){
        return 0;
    }
    var maxLen=1,currentLen=1,len=s.length,i,repeat;
    for(i=1; i<len; i++){
        repeat = s.substr(i-currentLen,currentLen).indexOf(s.substr(i,1));
        if(repeat === -1){
            currentLen++;
        }
        else{
            currentLen -= repeat;
        }
        if(maxLen<currentLen){
            maxLen = currentLen;
        }
    }
    return maxLen;
}; 

相關文章