字符串(滑动窗口) 3. 无重复字符的最长子串

3. 无重复字符的最长子串

  • 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例:

示例 1:
输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

思路1:切片实现滑动窗口(时间复杂度 O ( n 2 ) O(n^2)

定义一个滑动窗口列表,遍历字符串:
若字符不在窗口中,则添加,扩展窗口;
若字符已经在窗口中,则将窗口先缩减到窗口列表中字符出现位置的下一字符处,再添加当前字符,保证窗口列表中无重复字符。

代码实现1:

class Solution(object):
    def lengthOfLongestSubstring(self, s: str) -> int:
        if not s:
            return 0

        window = []     # 滑动窗口列表
        max_length = 0  # 最长串长度

        for c in s:
            # 如果字符不在滑动窗口中,则直接扩展窗口
            if c not in window:
                window.append(c)
            # 如果字符在滑动窗口中,则
            # 1. 从窗口中移除重复字符及之前的字符串部分,新字符串即为无重复字符的字符串
            # 2. 再扩展窗口
            else:
                window = window[window.index(c) + 1:]
                window.append(c)

            # 更新最大长度
            max_length = max(len(window), max_length)

        return max_length

思路2:使用哈希表优化滑动窗口(时间复杂度 O ( n ) O(n)

定义窗口左端变量 left 并设为-1,窗口长度为当前遍历到的值 - left。
使用 enumerate(s) 遍历索引及对应的字符串,使用哈希表存放映射关系,可能有三种情况:

  1. 哈希表中没有当前字符:直接向哈希表中添加映射关系,判断当前窗口长度是否大于最大长度,若是则更改最大长度为当前窗口长度;
  2. 哈希表中已经有当前字符,原有字符包含在窗口中:先将窗口左端变量left移动到原有字符位置(如图红色括号),再更改字符索引为当前索引值,即 {‘b’: 2};
  3. 哈希表中已经有当前字符,原有字符不包含在窗口中:直接向哈希表中更改映射关系(如字符a),判断当前窗口长度是否大于最大长度,若是则更改最大长度为当前窗口长度。

因为1、3操作相同,可将2作为if条件,1、3作为else条件。

在这里插入图片描述

代码实现2:

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        hash_map = {}
        max_len = 0
        left = -1
        
        for i, c in enumerate(s):
            if c in hash_map and hash_map.get(c) > left:
                left = hash_map.get(c)
                hash_map[c] = i
            else:
                hash_map[c] = i
                max_len = max(max_len, i-left)
            
        return max_len
发布了51 篇原创文章 · 获赞 4 · 访问量 3512

猜你喜欢

转载自blog.csdn.net/yhhuang17/article/details/104958538