LeetCode日常-简单-面试题59 - II. 队列的最大值
本文最后更新于:2020年9月27日 晚上
题目
请定义一个队列并实现函数 max_value 得到队列里的最大值.
要求函数max_value、push_back 和 pop_front 的时间复杂度都是O(1)。
若队列为空,pop_front 和 max_value 需要返回 -1
示例 1:
1 |
|
示例 2:
1 |
|
限制:
1 <= push_back,pop_front,max_value的总操作数 <= 10000
1 <= value <= 10^5
自解
1 |
|
没有留意题目的O(1)要求,看到了别人的评论才知道。
list.max() 时间复杂度为O(n),不符合要求。
大佬解法
思考过程
要想在O(1)
时间内做到取出最大值,我们可以想到,能否用一个cur_max
的变量,来记录并且比较每一次新入队的value
。
这个想法是极好的,但是如果队列是[4,3]
这个样子,cur_max
只会记下4是最大的,当调用一次pop_front()
后,此时队列为[3]
,而cur_max
没有变化,所以单个变量记录最大值行不通。
进一步地我们可以想到,一个变量不行,那我直接用一个辅助队列记录值OK不OK呢?
答案是OK的。我们让辅助队列的数从大到小排列好,要找最大值直接返回辅助队列的头部即可,同时这也是O(1)
时间复杂度的操作,完美契合题意。下面详细讲讲辅助队列怎么能够实现这个操作。
详细步骤
我们先初始化两个队列:
原始队列que = [],帮助我们记录原始数值。
辅助队列sort_que = [],帮助我们对原始数值进行排序。
对于原始队列que
,来一个就装一个,走一个就放一个,没啥好担心的。
重点是这个辅助队列sort_que
。
第一个问题:sort_que
里面怎么排序?
要回答这个问题,我们首先要知道,队列的性质是先进先出。
假设原始队列是[1,2]
,那么先走的那一位是队列里面的1。我们的sort_que
的头部理应为2,因为原始队列[1,2]
的最大值是2。即使对原始队列[1,2]
调用pop_front
造成1的离开,最大值依然是2,此时,我们仍然需要保持sort_que
的头部仍是2。
这个要求,就衍生出了sort_que队列的怎么排序了,请看代码:
1 |
|
这就是说,如果sort_que
不为空,并且sort_que
的最后一位元素小于当前入队元素value
的话,直接把最后一位元素弹走,直到sort_que
为空,或sort_que
的最后一位元素大于等于value
。这就保证了,sort_que
的头部总是原始队列que的最大值~
第二个问题:原始队列que
发生pop_front
时sort_que
该怎么变动?
这个其实比较简单,当que
弹出的数恰好等于sort_que
的头部元素时,咱把sort_que
的头部也跟着弹出就好。请看代码:
1 |
|
我们这里的que和sort_que假设是Python中的list形式,用pop(0)的方法可以弹出list的第一个元素,但这个的时间复杂度是O(n)
,这一点要注意。
Python中的deque可以对pop(0)
,就是popleft()
实现O(1)
的时间复杂度。
完整代码
1 |
|
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof
作者:quantumdriver
链接:https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof/solution/python-xiang-jie-wei-he-tian-jia-fu-zhu-dui-lie-ji/
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!