给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
由于我们需要找到给定字符串的最长无重复字符子串的长度,而且需要遍历字符串中全部可能的字符,因此可以使用滑动窗口来解。
-
设置
left = 0
和right = 0
为窗口的左右指针,窗口内不能含有重复字符 -
右移
right
,每移动一位判断right
指向的字符是否在窗口内已存在:- 如果已存在,则首先保存当前窗口的字符串,然后右移
left
,直到窗口内不包含right
指向的字符 - 如果不存在,则继续右移
right
,直到走到最后一位
- 如果已存在,则首先保存当前窗口的字符串,然后右移
-
如果走到了最后一位,且
right
指向的字符在窗口内不存在,首先保存子串,再退出循环 -
最后返回最长子串的长度
示意图如下所示:
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
# 特殊情况
if not s: return 0
if len(s) == 1: return 1
r = []
left, right = 0, 0
while right < len(s) - 1:
right += 1
# 如果right指针还没有走到最后,且当前right指向的字符在窗口内不存在,继续往后
if s[right] not in s[left:right] and right < len(s) - 1:
continue
# 如果right已经走到了最后,且当前right指向的字符在窗口内不存在,则保存窗口内字符串,退出循环
elif s[right] not in s[left:right] and right == len(s) - 1:
if len(s[left:right + 1]) > l:
l = len(s[left:right + 1])
break
else:
# 如果right指向的字符在窗口内已经存在,则先保存窗口字符串
# 再右移left指针,知道窗口字符串不再包含right指向的字符
if len(s[left:right]) > l:
l = len(s[left:right])
while s[right] in s[left:right]:
left += 1
return l