LeetCode刷题笔记(Python3)——3. 无重复字符的最长子串
(点击查看题目)
(点击查看官方题解)
注意:此题的官方题解使用的数据结构是列表,速度明显更慢(确实测试过),所以不推荐。有兴趣了解列表用法的各位可以点击链接参考。
LeetCode刷题笔记(Python3)——3. 无重复字符的最长子串
初始解法
由于个人已知在Python中需要查找时,使用字典(dict)的速度明显快于使用列表(list),所以直接采用字典辅助编程。
# 时间复杂度:O(N) 空间复杂度:O(N)
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
len_max, head, d = 0, 0, dict()
for i, char in enumerate(s):
if char in d: # 该字符出现过
len_max = max(len_max, i - head)
new_head = d[char] + 1
[d.pop(k) for k in s[head: new_head]] # 剔除旧的无用字符
head = new_head
d[char] = i # 将新字符加入字典
return max(len_max, len(s) - head)
1. Python独门技巧:列表生成式
列表生成式可以快速生成具有特定规律的列表,也可以快速进行具有特定规律的批量操作。
[i**2 for i in range(4)] # [0, 1, 4, 9]
[d.pop(k) for k in s] # 把字典d中键值为s中字符的所有键值对从d中去除
2. 在控制台输出字典中键值对的方法
这一技巧也可以用于程序的debug。
d = {
2:'b', 1:'a', 3:'c'}
for j in d:
print(j, d[j])
# result:
# 2 b
# 1 a
# 3 c
优化解法
参考了用时最短的几个代码,并着手进一步简化后得到了下面的优化解法。该算法不仅更短,而且更快。
# 时间复杂度:O(N) 空间复杂度:O(N)
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
len_max, start, d = 0, -1, dict()
for i, char in enumerate(s):
if char in d and d[char] > start: # 该字符出现过 且 上次出现在当前子串中
start = d[char]
else:
len_max = max(len_max, i - start)
d[char] = i
return len_max
初始算法慢的主要原因在于需要从字典中去除旧的键值。相对地,优化算法更快速的原因就是只需更新键值即可,无需去除键值,操作量明显减少。核心点在于初始算法过于启发式,而优化算法的算法思想明显更好。