LeetCode 3——無重複字元的最長子串
阿新 • • 發佈:2018-12-18
1. 題目
2. 解答
2.1. 方法一
我們從前往後遍歷字串,start 代表最長子串的起始位置,一開始設定為零。
如果沒有遇到重複字元,則更新子串的長度,向後遍歷。
如果遇到重複字元時,則更新字串起始位置為上一個相同字元的後面一個位置,同時更新子串長度。
重複上面這個過程,直到遍歷完畢。
‘abcabc’,start = 0,str_len = 1, 2, 3 此時第二次遇到 ‘a’,start = 1,str_len = 3 此時第二次遇到 ‘b’,start = 2,str_len = 3 此時第二次遇到 ‘c’,start = 3,str_len = 3
class Solution :
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
max_len = 0
str_len = 0
start = 0 # 最長子串的起始位置
index = 0 # 上一個相同字元在子串中的位置,是一個相對位置,不是在原字串中的位置
for i in range(len(s)):
if (s[i] not in s[start:i]):
str_len += 1
# 如果遇到重複字元,更新子串的起始位置為上一個相同字元的後面一個位置
# 同時我們需要更新子串長度
else:
max_len = max(max_len, str_len)
index = s[start:i].find(s[i])
str_len = str_len - index
start = start + index + 1
max_len = max(max_len, str_len) # 一直沒有遇到重複字元
return max_len
2.2. 方法二
方法一中,我們每次判斷當前字元是否為重複字元時,都需要在子串中進行搜尋,更新子串起始位置時,也要在子串中搜索上一個相同字元的位置,效率很低。
其實我們需要知道的就是一個子串的起始位置,然後往後遍歷的時候只需要在適當的時候更新這個起始位置重新計運算元串長度即可。
因此,我們可以建立一個當前字元和當前字元下一個位置的對映。
所有對映全部初始化為零,start = 0。從前往後開始遍歷字串,同時更新對映,計運算元串長度。
如果當前字元的對映大於 start,說明在 satrt 後面出現過當前字元,就更新 start。
class Solution:
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
max_len = 0
str_len = 0
start = 0 # 最長子串的起始位置
index = 0 # 重複的字元在子串中的位置
# 初始化對映
table = []
for i in range(128):
table.append(0)
for i in range(len(s)):
start = max(start, table[ord(s[i])])
str_len = i - start + 1
max_len = max(max_len, str_len)
table[ord(s[i])] = i + 1
return max_len
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int table[128] = {0}; // 自動初始化為零
int max_len = 0;
int str_len = 0;
int start = 0;
string::iterator it = s.begin();
for (int j = 0; it != s.end(); it++, j++)
{
start = start > table[*it] ? start : table[*it];
table[*it] = j + 1;
str_len = j - start + 1;
max_len = max_len < str_len ? str_len : max_len;
}
return max_len;
}
};
獲取更多精彩,請關注「seniusen」!