队列
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。
堆排序
- 什么是堆?
堆是一种数据结构,它是一颗完全二叉树。
堆分为最大堆和最小堆:
最大堆:任意节点的值不大于其父亲节点的值。
最小堆:任意节点的值不小于其父亲节点的值 - 堆有什么用途?
堆最常用于优先队列以及相关动态问题。
优先队列指的是元素入队和出队的顺序与时间无关,既不是先进先出,也不是先进后出,而是根据元素的重要性来决定的。
例如,操作系统的任务执行是优先队列。一些情况下,会有新的任务进入,并且之前任务的重要性也会改变或者之前的任务被完成出队。而这个出队、入队的过程利用堆结构,时间复杂度是O(log2_n)。
LeetCode
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
# 解法一
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
rlist = []
if nums != [] and k != 0:
max_index = [] # 存放最大值
for i in range(len(nums)):
# max_index 列表不为空且 nums[i] 大于 max_index最后一个,则弹出
while max_index and nums[i] >= nums[max_index[-1]]:
max_index.pop(-1)
max_index.append(i) # 把现在下标的值放进去
if (i - k) == max_index[0]:
max_index.pop(0) # 保证 max_index 的头是最新最大的
if i >= k - 1:
rlist.append(nums[max_index[0]])
return rlist
# 解法二
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
if nums:
return [max(nums[i:i+k]) for i in range(len(nums)-k+1)]
else:
return nums