LeetCode刷题笔记(Python3)——3. 无重复字符的最长子串(难度:中等)(2021-05-11)

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

初始算法慢的主要原因在于需要从字典中去除旧的键值。相对地,优化算法更快速的原因就是只需更新键值即可,无需去除键值,操作量明显减少。核心点在于初始算法过于启发式,而优化算法的算法思想明显更好。

猜你喜欢

转载自blog.csdn.net/AbaloneVH/article/details/116664260
今日推荐