• 【队列-01】队列题目解析


    目录

    1. 面试题59 - I. 滑动窗口的最大值/239. 滑动窗口最大值
    2. 面试题59 - II. 队列的最大值
    3. 剑指 Offer 13. 机器人的运动范围

       

    队列:普通队列满足,先进先出,目前也支持双端出的队列形式。

       

    一、面试题59 - I. 滑动窗口的最大值/239. 滑动窗口最大值

    1.1 问题

    给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值。

    进阶:你能在线性时间复杂度内解决此题吗?

    示例:

    输入: nums = [1,3,-1,-3,5,3,6,7], k = 3

    输出: [3,3,5,5,6,7]

    解释:

    滑动窗口的位置 最大值

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

    [1 3 -1] -3 5 3 6 7 3

    1 [3 -1 -3] 5 3 6 7 3

    1 3 [-1 -3 5] 3 6 7 5

    1 3 -1 [-3 5 3] 6 7 5

    1 3 -1 -3 [5 3 6] 7 6

    1 3 -1 -3 5 [3 6 7] 7

    提示:

    1 <= nums.length <= 10^5

    -10^4 <= nums[i] <= 10^4

    1 <= k <= nums.length

    1.2 解析

    利用双向队列,按照递减的排序来做,滑动的过程中可能会剔除一些没有可能的小数字

    1.3 代码

    class Solution:

        def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:

            if not nums or k == 0return []

            deque = collections.deque()   #定义双向队列,两边都可以进出

            for i in range(k): 未形成窗口

                while deque and deque[-1] < nums[i]: #保持deque是一个递减的数组

                    deque.pop()

                deque.append(nums[i])  #根据上面的调整,插入新来的数,也能保持递减

            res = [deque[0]]  #将最前面的数插入加过中,因为此时就是最大的

            for i in range(k, len(nums)): 形成窗口后

                if deque[0] == nums[i - k]: #如果最大值落在滑动窗口的左侧,要将其删除

                    deque.popleft()

                while deque and deque[-1] < nums[i]: #保持deque是一个递减的数组

                    deque.pop()

                deque.append(nums[i])

                res.append(deque[0])

            return res

    二、面试题59 - II. 队列的最大值

    2.1 问题

    请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_valuepush_back pop_front 的均摊时间复杂度都是O(1)。若队列为空,pop_front max_value 需要返回 -1

    示例 1

    输入:

    ["MaxQueue","push_back","push_back","max_value","pop_front","max_value"]

    [[],[1],[2],[],[],[]]

    输出: [null,null,null,2,1,2]

    示例 2

    输入:

    ["MaxQueue","pop_front","max_value"]

    [[],[],[]]

    输出: [null,-1,-1]

    2.2 代码

    import queue

    class MaxQueue:

        """1队列+1数组"""

        def __init__(self):

            self.queue = queue.Queue()

            self.stack = []      #  用于存放最大值的数组

        def max_value(self) -> int:

            return self.stack[0if self.stack else -1

        def push_back(self, value: int) -> None:

            self.queue.put(value)     

            while self.stack and self.stack[-1] < value: #保持stack是递减的形式,并且该数值之前,都最大

                self.stack.pop()

            self.stack.append(value)

        def pop_front(self) -> int:

            if not self.stack: return -1 # stack为空,即对应的queue也为空了

            ans = self.queue.get()

            if ans == self.stack[0]:

                self.stack.pop(0)

            return ans

    三、剑指 Offer 13. 机器人的运动范围

    3.1 问题

    地上有一个mn列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

       

    示例 1

    输入:m = 2, n = 3, k = 1

    输出:3

    示例 2

    输入:m = 3, n = 1, k = 0

    输出:1

    3.2 代码

    class Solution:

       

        def sum_rc(self,row,col):

            tmp = 0

            while row > 0:

                tmp += row % 10

                row //=  10

            while col > 0 :

                tmp += col % 10

                col //= 10

            return tmp

       

        def movingCount(self, m: int, n: int, k: int) -> int:

            marked = set()  将访问过的点添加到集合marked,(0,0)开始

            queue = collections.deque()

            queue.append((0,0))

            while queue:

                x, y = queue.popleft()

                if (x,y) not in marked and self.sum_rc(x,y) <= k:

                    marked.add((x,y)) 

                    for dx, dy in [(1,0),(0,1)]:  仅考虑向右和向下即可,注意在if内部

                        if 0 <= x + dx < m and 0 <= y + dy < n:

                            queue.append((x+dx,y+dy))  #增加两个坐标

            return len(marked)  

       

    参考文献

    1https://leetcode-cn.com/

    2一题的答案动画解析

    3第二题动画解析

  • 相关阅读:
    Tomcat example 应用信息泄漏漏洞及修复
    Tomcat远程代码执行漏洞(CVE-2017-12615)修复
    Oracle安装和使用说明
    关于乱码的问题
    js 判断字符串中是否包含某个字符串
    com.alibaba.fastjson.JSONPathException: expect '], but 'y'
    java.util.UnknownFormatConversionException: Conversion = ''';
    nested exception is java.lang.NoClassDefFoundError: org/codehaus/jettison/json/JSONObject异常的解决办法
    复选框做成单选的效果
    sFlow-rt安装部署
  • 原文地址:https://www.cnblogs.com/yifanrensheng/p/13771886.html
Copyright © 2020-2023  润新知