题目
思路
-
暴力
-
线性法
从前到后扫描,如果有重复字符,更新长度 -
优化的线性法
慢指针不需要从左到右移动,用哈希表保存目标位置,减少比较次数
线性法
线性法复杂度
-
时间复杂度
快慢指针,最多遍历两次
快指针添加到哈希集合,慢指针删除
表格尺寸为 n ∗ O ( 1 ) + n ∗ O ( 1 ) = O ( n ) n*\mathcal{O}(1)+n*\mathcal{O}(1)=\mathcal{O}(n) n∗O(1)+n∗O(1)=O(n) -
空间复杂度
最坏情况,没有重复字符,所有字符都加入了集合, O ( n ) \mathcal{O}(n) O(n)
线性法代码
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
char_set = set()
max_len = 0
i = 0
for ch in s: # 快指针
while ch in char_set:
# 快指针指向的字符在集合中,就不断将慢指针往前移,将慢指针指向的字符从集合中移除
char_set.remove(s[i]) # 移除
i += 1 # 慢指针前进
char_set.add(ch) # 移除后将当前位置字符加入
max_len = max(max_len, len(char_set))
return max_len
优化的线性法
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
hash_map = dict() # 记录字符上次出现的位置
max_len = 0
i = 0
for j in range(len(s)): # 快指针
if s[j] in hash_map: # 慢指针
# 出现过,则慢指针跳跃
# 上次出现的位置可能比i小,所以要取与i的max
# 如: 'deabcae' ,j在最后一个位置时,hash_map['e'] = 1,已经不在当前的串中(被两个'a'截断)
i = max(i, hash_map[s[j]] + 1)
hash_map[s[j]] = j # 更新哈希表中的位置
max_len = max(max_len, j - i + 1) # 当前的长度与最大长度比较
return max_len