写在前面
时值新冠肺炎关键时期,大家一定要勤通风,多洗手,注意个人卫生,外出戴好口罩。让我们众志成城,打赢这场没有硝烟的疫情攻坚战。
1.题目描述如下:
请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_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]
限制:
1 <= push_back,pop_front,max_value的总操作数 <= 10000
1 <= value <= 10^5
通过次数3,394提交次数7,306
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.题目意思解读
- max_value:返回队列最大值。队列为空时,返回-1。
- pop_front:删除队列尾部元数,并输出该数值。队列为空时,返回-1。
- push_back:往队列里面输入值。
每次输入一个列表,列表里面有若干操作,同样输出也对应一个列表,有返回值就是返回值,无返回值则是null。当然这不是重点。下面拿示例一来解释:
示例 1:
输入:
[“MaxQueue”,“push_back”,“push_back”,“max_value”,“pop_front”,“max_value”]
[[],[1],[2],[],[],[]]
输出: [null,null,null,2,1,2]
- 创建队列。输出null。
- 往队列中加入1。此时队列为[1]。输出null。
- 往队列中加入2。此时队列为[1, 2]。输出null。
- 找最大值。此时队列为[1, 2]。输出2。
- 移除队首元素。此时队列为[2]。输出1(输出移除的元素)。
- 找最大值。此时队列为[2]。输出2。
3.解题思路
之前没接触过用python3写队列,因此真的是一点思路都没有。后来在评论区,看到大神用C++解题,灵机一动,干脆先用C++写一遍,再用python3.7来写一下好了。
首先明确,一个队列肯定不够,查最大值明显是O(n),毕竟题目要求的复杂度O(1)。因此这里想到新建两个队列,一个用来操作,另一个用来存最大值,这就很灵性。
先附上C++代码(评论区大神的代码,侵删)
class MaxQueue {
public:
MaxQueue() {
}
int max_value() {
return que.empty()?-1:dq.front();
}
void push_back(int value) {
que.push(value);
while(!dq.empty()&&dq.back()<value)
dq.pop_back();
dq.push_back(value);
}
int pop_front() {
if(que.empty())
return -1;
int t=que.front();
que.pop();
if(t==dq.front())
dq.pop_front();
return t;
}
private:
queue<int> que;
deque<int> dq;
};
代码解释:
建立两个队列,一个用来进行操作(que),一个用来存最大值(dq)。
第一个函数max_value(),取最大值,就是返回-1(队列为空)或dq的队首。
第二个函数push_back(),往队列里面加value。同时需要更新dq,将dq队列尾部和value进行比较,如果队尾元素小,就移除,继续循环。这样能保证value要不就最大,要不就有比他大的在队首。当然,队列如果是空的,就直接把value添加就好了。
第三个函数pop_front(),移除队首。如果是空,返回-1;非空,移除就好了。如果队首同时是最大值,则dq的队首也要移除(因为dq在其队首储存最大值),返回移除值。
总的来说,看懂题目后,其实很简单,还是自己太菜了,太久没敲代码了。
接下来,我就用python3又写了一遍,中途还把C++和python3的语法搞混了,错了好几遍。另外,可能细节没写好,耗时感人。
附上python3代码:
class MaxQueue:
def __init__(self):
self.que = []
self.dq = []
def max_value(self) -> int:
if len(self.dq):
return self.dq[0]
else:
return -1
def push_back(self, value: int) -> None:
self.que.append(value)
while(len(self.dq) and self.dq[len(self.dq)-1]<value):
self.dq = self.dq[:len(self.dq)-1]
self.dq.append(value)
def pop_front(self) -> int:
if (len(self.que) == 0):
return -1;
t = self.que[0]
self.que = self.que[1:]
if (t == self.dq[0]):
self.dq = self.dq[1:]
return t
# Your MaxQueue object will be instantiated and called as such:
# obj = MaxQueue()
# param_1 = obj.max_value()
# obj.push_back(value)
# param_3 = obj.pop_front()
也没啥难度,就是用python3模拟出一个队列就好了。我这里用的是列表代替。加入操作就用列表的类函数.append(x),移除队首就用 list1 = list1[1:],移除队尾就用 list2 = list2[:len(list2)-1] ,都是很简单的切片操作。python3的列表修改大小操作,实际上是新建了一个列表,感兴趣的可以自己去查查python的底层实现。
最后勉励一下自己和各位在坚持的朋友,
有志者,事竟成。破釜沉舟,百二秦关终属楚;
苦心人,天不负。卧薪尝胆,三千越甲可吞吴。