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

写在前面

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

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:

扫描二维码关注公众号,回复: 11129199 查看本文章

输入:
[“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的底层实现。

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

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

发布了18 篇原创文章 · 获赞 1 · 访问量 801

猜你喜欢

转载自blog.csdn.net/shuaishuaihyh/article/details/104711067