您的位置:首页 > 编程语言 > C语言/C++

leetcode1548题:面试题59 - II. 队列的最大值(2020/3/7/每日一题)(python3和C++解法)

shuaishuaihyh 2020-03-15 18:23 97 查看 https://blog.csdn.net/shuaishu

写在前面

时值新冠肺炎关键时期,大家一定要勤通风,多洗手,注意个人卫生,外出戴好口罩。让我们众志成城,打赢这场没有硝烟的疫情攻坚战。

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]

  1. 创建队列。输出null。
  2. 往队列中加入1。此时队列为[1]。输出null。
  3. 往队列中加入2。此时队列为[1, 2]。输出null。
  4. 找最大值。此时队列为[1, 2]。输出2。
  5. 移除队首元素。此时队列为[2]。输出1(输出移除的元素)。
  6. 找最大值。此时队列为[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的底层实现。

最后勉励一下自己和各位在坚持的朋友,

有志者,事竟成。破釜沉舟,百二秦关终属楚;
苦心人,天不负。卧薪尝胆,三千越甲可吞吴。

  • 点赞 1
  • 收藏
  • 分享
  • 文章举报
毛毛苦练吉吉国王 发布了1 篇原创文章 · 获赞 1 · 访问量 268 私信 关注
标签: 
相关文章推荐