题目描述
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
解题思路1: 双指针法+暴力循环 O(n^2)
求最长子串的长度, 子串一定是连续的, 所以我们使用2个指针来进行遍历.
- 如果尾指针元素不在2个指针所组成的子串, 那么尾指针往后移动, 并且更新最大长度
- 如果尾指针在子串中, 那么我们将头指针往移动到重复元素位置的后边, 保证2个指针所组成的子串没有重复元素, 然后继续遍历尾指针
示例代码1:
def lengthOfLongestSubstring(self, s: str) -> int:
if not s:
return 0
left, right = 0, 0
result = 1
while right < len(s) - 1:
right += 1
if s[right] not in s[left:right]:
result = max(right - left + 1, result)
else:
while s[right] in s[left:right]:
left += 1
return result
解题思路2: 双指针法+Map O(n)
同样的双指针思想, 我们使用map可以将时间复杂度优化到O(n)
- 判断当前遍历的字符是否在map中, 如果不在map中, 我们就将当前字符加入到map, 以 字符为key, index+1 为value
- 如果在map中, 我们就将头指针设置为之前记录在map中,当前元素的index
示例代码2:
def lengthOfLongestSubstring(self, s: str) -> int:
if not s:
return 0
left = 0
result = 0
dic = {}
for i in range(0, len(s)):
right = s[i]
if right in dic:
left = max(dic[right], left)
dic[right] = i + 1
result = max(result, i - left + 1)
return result