数据结构|LeetCode(力扣)经典题:队列

本文介绍了如何使用队列解决LeetCode中的经典问题,包括无重复字符的最长子串和滑动窗口最大值。通过滑动窗口的概念,详细讲解了双端队列在解题中的应用,提供了解题思路和优化方法。
摘要由CSDN通过智能技术生成

队列

更多请查看我的专栏: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)

  1. 初始化子串的长度len_s1=0、最大不含重复字符的最长子串的长度max_s1=0;设队列lookup=set(),并初始化队首位于字符串的序号left=0
  2. 循环for i in range(len(s))
    1. 从字符串左边开始,取s[i]放入队列末尾,len_s1+=1
    2. 用while判断s[i]是否重复?while s[i] in lookup
      1. 如果在,移除队列首的元素lookup.remove(s[left]),左序号右移``left+=1,子串长度减少len_s1-=1`,跳至2.2继续判断;
    3. 如果不在,s[i]加入队列末尾lookup.add(s[i]);并判果max_s1<len_s1?,如果是,那么max_s1=len_s1;
  3. 返回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]
解释:

  滑动窗口的位置                最大值

---------------               -----

[
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值