一周编程集训day3:队列与堆

一周编程集训day3:队列与堆

1 任务

队列与堆:学习队列思想及堆排序思想,并完成leetcode上的返回滑动口中的最大值(239)!并同 时温习前二天内容,做出总结!!

2 概念介绍

  1. 队列(常用数据结构之一)是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
    队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。
    在这里插入图片描述
  2. 堆(Heap):从根结点开始,每个结点可以有左、右两个结点,元素优先将每一层按从左到右的方式填满,即父结点最多有两个子结点,有右子结点就一定会有左子结点,同一层的某个结点左边一定是填满的。
    接下来,说一说堆中元素摆放的规则。分为两种情况,有最大堆和最小堆,最小堆就是根结点元素的值是所有元素中最小的,最大堆则相反,下图是一个最小堆。在一个摆放好元素的最小堆中,可以看到,父结点中的元素一定比子结点的元素要小,但对于左右结点的大小则没有规定谁大谁小。接下来,说一说堆中元素摆放的规则。堆分为两种情况,有最大堆和最小堆,最小堆就是根结点元素的值是所有元素中最小的,最大堆则相反,下图是一个最小堆。在一个摆放好元素的最小堆中,可以看到,父结点中的元素一定比子结点的元素要小,但对于左右结点的大小则没有规定谁大谁小。
    关于最小堆(最大堆)的常用的操作有插入新元素和取最小值(最大值)。关于最小堆(最大堆)的常用的操作有插入新元素取最小值(最大值)
    1)插入操作就是直接把新的元素放到最下面一层的可用的最左边,如下图中的X,当X比父结点3要大,那么堆的结构是稳定的,插入操作即完成;如果X比3要小,那么就不符合我们之前说的规则,就要把父结点3和X结点交换,交换完后还没结束,还要比较X和交换完后的父结点即1的大小,如果比1小,则结束,否则仍要继续交换直到稳定。
    2)取小值操作,直接将根结点元素返回;此时根结点为空,需要把最后一个叶结点(即结点8)放到根结点的位置,此时把元素8和左右子结点比较小的那一个(即3)作比较,如果比子结点大,则交换,以此累推,直到堆结构稳定。
    在这里插入图片描述

3 leetcode

1.239.滑动窗口最大值

给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口 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
 注意:

你可以假设 k 总是有效的,1 ≤ k ≤ 输入数组的大小,且输入数组不为空。

python解答思路:一开始没思路,参考了网上思路,给出以下代码解答。

class Solution(object):
    def maxSlidingWindow(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        if not nums:return []
        res,window = [],[]
        for i,x in enumerate(nums):
            if i >= k and window[0] <= i - k:
                window.pop(0)
            while window and nums[window[-1]] <= x:
                window.pop()
            window.append(i)
            if i >= k - 1:
                res.append(nums[window[0]])
        return res

leetcode提交结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值