3. Longest Substring Without Repeating Characters 无重复字符的最长子串
1. 原始题目
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其
长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b"
,所以其长度为 1。
示例 3:
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是"wke"
,所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"
是一个子序列,不是子串。
2. 思路
双指针法。[i,j]左闭又闭区间为当前子串,如果j+1位置的元素没有重复则继续加入,否则i+1直到没有重复元素。那么如何确定是否重复呢,有两种方法,第一种是循环判断在字串中是否仍有重复的元素。第二种是构建一个字典,来判断当前元素是否已经出现过。下面给出了两种解法。
3. 解题
方法1.循环判断是否有重复
1 class Solution:
2 def lengthOfLongestSubstring(self, s: str) -> int:
3 if not s:return 0
4 i,j=0,0 # 单元素肯定是目前的最长子串
5 res = 1 # 此时长度为1
6 temp = s[0] # 子串
7 while(i<len(s) and j+1<len(s)):
8 if s[j+1] in temp: # 如果下一个元素有重复
9 while(s[j+1] in temp): # 则i循环往前直到不包含该重复元素
10 i+=1
11 temp = temp[1:]
12 else:
13 j+=1 # 没有重复元素就继续往前
14 temp+=s[j]
15 res = max(len(temp),res) # 返回最长的子串长度
16
17 return res
方法2.利用字典判断当前元素是否有重复
1 from collections import defaultdict
2 class Solution:
3 def lengthOfLongestSubstring(self, s: str) -> int:
4 if not s:return 0
5 d = defaultdict(int)
6 i,j=0,-1 # [i,j] 左闭又闭区间为初始子串
7 res = 0
8 while(i<len(s)):
9 if j+1<len(s) and d[s[j+1]]==0: # 如果j+1个元素没有出现过,则j继续+1
10 j+=1
11 d[s[j]]+=1
12 else: # 出现过则i位置字典对应的次数-1,i右移
13 d[s[i]]-=1
14 i+=1
15 res = max(res,j-i+1)
16
17 return res