3. Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters.
Example 1:
Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
Example 2:
Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Example 3:
Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Note that the answer must be a substring,"pwke" is a subsequence and not a substring.
解法
思路:滑动窗口法
"pwwkew"
1 p {p:0} max=1 start=0
2 pw {p:0,w:1} max=2 start=0
3 pww {p:0,w:2} max=2 start=3
4 pwwk {p:0,w:2,k:3} max=2 start=3
5 pwwke {p:0,w:2,k:3,e:4} max=3 start=3
6 pwwkew {p:0,w:5,k:3,e:4} max=3 end
从第三行开始出现了第一个重复的字符w
,此时start
的位置为初始位置0
,这是状态发生转移的条件:字符出现重复,并且重复字符出现的位置i大于start,这就意味着在s[start:i]
之间出现了重复的字符,此时只需要将start
移动到w
上次出现的位置之后就行了。转换成程序语言就是:
# c is 'w'
if c in last_seen and last_seen[c] >= start:
start = last_seen[c] + 1
状态发生变化的时候,子串的长度一定不会大于最大长度,因此该次不需要比较。因为遍历时指针每次只向前移动一个字符,而发生状态转移时至少会移动一个字符(例如从5到6,start正好位于w
上一次出现的位置),这就意味着,状态转移时得到的新子串一定不会比上一次长。
如果没有发生状态转移,那么遍历会使当前子串长度加一,要统计更新后的最长字符串长度。
longest = max((i - start + 1), longest)
在每次遍历后更新字典,记录字符出现位置:
last_seen[c] = i
完整代码:
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
last_seen = {}
start = 0
longest = 0
for i, c in enumerate(s):
if c in last_seen and last_seen[c] >= start:
# repeating words show in s[start: i],
# so update start. start move forward
# one step from last seen c, then we
# can assure that from the start to i,
# there is no repeated character.
start = last_seen[c] + 1
else:
# c is not in last_seen or c is ahead of start,
# which means from start to i there is no repeating characters
longest = max(longest, i - start + 1)
last_seen[c] = i
return longest
感觉还是没有写清楚,思路还是不够清晰。
Last updated
Was this helpful?