队列
更多请查看我的专栏:LeetCode(力扣)刷题指南
可直接在
LeetCode
中搜索题目名称
文章目录
1. 无重复字符的最长子串:滑动窗口
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
1.1 解决方案
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
len_s1=0
max_s1=0
lookup=set() #注意set()的用法!
left=0
for i in range(len(s)):
len_s1+=1
while s[i] in lookup:
lookup.remove(s[left])
left+=1
len_s1-=1
lookup.add(s[i])
if max_s1<len_s1:max_s1=len_s1
return max_s1
**算法思路:**时间复杂度O(n)
- 初始化子串的长度
len_s1=0
、最大不含重复字符的最长子串的长度max_s1=0
;设队列lookup=set()
,并初始化队首位于字符串的序号left=0
- 循环
for i in range(len(s))
:- 从字符串左边开始,取
s[i]
放入队列末尾,len_s1+=1
; - 用while判断s[i]是否重复?
while s[i] in lookup
- 如果在,移除队列首的元素
lookup.remove(s[left])
,左序号右移``left+=1,子串长度减少
len_s1-=1`,跳至2.2继续判断;
- 如果在,移除队列首的元素
- 如果不在,s[i]加入队列末尾
lookup.add(s[i])
;并判果max_s1<len_s1?,如果是,那么max_s1=len_s1;
- 从字符串左边开始,取
- 返回max_s1。
优化思路:
上述的方法最多需要执行 2n 个步骤。事实上,它可以被进一步优化为仅需要 n 个步骤。我们可以定义字符到索引的映射,而不是使用集合来判断一个字符是否存在。 当我们找到重复的字符时,我们可以立即跳过该窗口。
也就是说,如果队列s[i]在[i,j)范围内有与j’重复的字符,我们不需要逐渐增加i。我们可以直接跳过[i,j’]范围内的所有元素,并将i变成j’+1。
2. 滑动窗口最大值
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
示例:
输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7]
解释:滑动窗口的位置 最大值 --------------- ----- [