• [LeetCode] 1670. Design Front Middle Back Queue


    Design a queue that supports push and pop operations in the front, middle, and back.

    Implement the FrontMiddleBack class:

    • FrontMiddleBack() Initializes the queue.
    • void pushFront(int val) Adds val to the front of the queue.
    • void pushMiddle(int val) Adds val to the middle of the queue.
    • void pushBack(int val) Adds val to the back of the queue.
    • int popFront() Removes the front element of the queue and returns it. If the queue is empty, return -1.
    • int popMiddle() Removes the middle element of the queue and returns it. If the queue is empty, return -1.
    • int popBack() Removes the back element of the queue and returns it. If the queue is empty, return -1.

    Notice that when there are two middle position choices, the operation is performed on the frontmost middle position choice. For example:

    • Pushing 6 into the middle of [1, 2, 3, 4, 5] results in [1, 2, 6, 3, 4, 5].
    • Popping the middle from [1, 2, 3, 4, 5, 6] returns 3 and results in [1, 2, 4, 5, 6].

    Example 1:

    Input:
    ["FrontMiddleBackQueue", "pushFront", "pushBack", "pushMiddle", "pushMiddle", "popFront", "popMiddle", "popMiddle", "popBack", "popFront"]
    [[], [1], [2], [3], [4], [], [], [], [], []]
    Output:
    [null, null, null, null, null, 1, 3, 4, 2, -1]
    
    Explanation:
    FrontMiddleBackQueue q = new FrontMiddleBackQueue();
    q.pushFront(1);   // [1]
    q.pushBack(2);    // [1, 2]
    q.pushMiddle(3);  // [1, 3, 2]
    q.pushMiddle(4);  // [1, 4, 3, 2]
    q.popFront();     // return 1 -> [4, 3, 2]
    q.popMiddle();    // return 3 -> [4, 2]
    q.popMiddle();    // return 4 -> [2]
    q.popBack();      // return 2 -> []
    q.popFront();     // return -1 -> [] (The queue is empty)

    Constraints:

    • 1 <= val <= 109
    • At most 1000 calls will be made to pushFrontpushMiddlepushBackpopFrontpopMiddle, and popBack.

    设计前中后队列。

    请你设计一个队列,支持在前,中,后三个位置的 push 和 pop 操作。

    请你完成 FrontMiddleBack 类:

    FrontMiddleBack() 初始化队列。
    void pushFront(int val) 将 val 添加到队列的 最前面 。
    void pushMiddle(int val) 将 val 添加到队列的 正中间 。
    void pushBack(int val) 将 val 添加到队里的 最后面 。
    int popFront() 将 最前面 的元素从队列中删除并返回值,如果删除之前队列为空,那么返回 -1 。
    int popMiddle() 将 正中间 的元素从队列中删除并返回值,如果删除之前队列为空,那么返回 -1 。
    int popBack() 将 最后面 的元素从队列中删除并返回值,如果删除之前队列为空,那么返回 -1 。
    请注意当有 两个 中间位置的时候,选择靠前面的位置进行操作。比方说:

    将 6 添加到 [1, 2, 3, 4, 5] 的中间位置,结果数组为 [1, 2, 6, 3, 4, 5] 。
    从 [1, 2, 3, 4, 5, 6] 的中间位置弹出元素,返回 3 ,数组变为 [1, 2, 4, 5, 6] 。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/design-front-middle-back-queue
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    这是一道设计题,思路是用两个双端队列deque做。首先我需要创建两个deque,left 和 right。left 在左边,right 在右边,left 的右侧跟 right 的左侧相接。当元素个数为偶数的时候,left 和 right 的元素个数是相同的;但是当元素个数为奇数的时候,right 会比 left 多一个元素。

    pushFront() - 只会从 left 的左侧加元素

    pushBack() - 只会从 right 的右侧加元素

    popFront() - 只会从 left 的左侧弹出元素

    popBack() - 只会从 right 的右侧弹出元素

    pushMiddle() - 如果两个 deque 元素个数相同,则加入 right;反之则加入 left

    popMiddle() - 如果两个 deque 元素个数相同,则试图弹出 left 的最右侧元素(注意有可能为空);反之则弹出 right 最左侧的元素

    最后我们还需要一个 balance() 函数来帮助平衡两个 deque 的元素个数,使得 right 最多比 left 多一个元素。

    时间O(1) - amortized,因为这是ArrayDeque决定的

    空间O(n)

    Java实现

     1 class FrontMiddleBackQueue {
     2     Deque<Integer> left;
     3     Deque<Integer> right;
     4 
     5     public FrontMiddleBackQueue() {
     6         left = new ArrayDeque<>();
     7         right = new ArrayDeque<>();
     8     }
     9 
    10     //   addFromHere -> left -- right
    11     public void pushFront(int val) {
    12         left.addFirst(val);
    13         balance();
    14     }
    15 
    16     public void pushMiddle(int val) {
    17         if (left.size() == right.size()) {
    18             right.addFirst((val));
    19         } else {
    20             left.addLast(val);
    21         }
    22     }
    23 
    24     public void pushBack(int val) {
    25         right.addLast(val);
    26         balance();
    27     }
    28 
    29     public int popFront() {
    30         Integer num = left.pollFirst();
    31         if (num == null) {
    32             num = right.pollFirst();
    33             return num == null ? -1 : num;
    34         } else {
    35             balance();
    36             return num;
    37         }
    38     }
    39 
    40     public int popMiddle() {
    41         if (left.size() == right.size()) {
    42             Integer num = left.pollLast();
    43             return num == null ? -1 : num;
    44         } else {
    45             return right.pollFirst();
    46         }
    47     }
    48 
    49     public int popBack() {
    50         Integer num = right.pollLast();
    51         balance();
    52         return num == null ? -1 : num;
    53     }
    54 
    55     private void balance() {
    56         if (left.size() > right.size()) {
    57             right.addFirst(left.pollLast());
    58         } else if (left.size() + 2 == right.size()) {
    59             left.addLast(right.pollFirst());
    60         }
    61     }
    62 }
    63 
    64 /**
    65  * Your FrontMiddleBackQueue object will be instantiated and called as such:
    66  * FrontMiddleBackQueue obj = new FrontMiddleBackQueue();
    67  * obj.pushFront(val);
    68  * obj.pushMiddle(val);
    69  * obj.pushBack(val);
    70  * int param_4 = obj.popFront();
    71  * int param_5 = obj.popMiddle();
    72  * int param_6 = obj.popBack();
    73  */

    LeetCode 题目总结

  • 相关阅读:
    优质Android小部件:索尼滚动相册
    Linux常用命令:文件与目录
    Android高效计算——RenderScript(二)
    Android高效计算——RenderScript(一)
    实用控件分享:自定义逼真相机光圈View
    Binder中的asInterface解析
    Android Adapter的几个方法
    Android中各种Drawable总结
    win10配置CUDA+Tensorflow2.0的一些经验
    关于Flash Helper Service的问题
  • 原文地址:https://www.cnblogs.com/cnoodle/p/14672724.html
Copyright © 2020-2023  润新知