[路飞]_leetcode刷题_1670. 设计前中后队列

104 阅读2分钟

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战

题目

1670. 设计前中后队列

请你设计一个队列,支持在前,中,后三个位置的 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] 。

思路:

有了之前循环队列和循环双端队列的经验,这题的思路其实就是两种,一是用数组实现,二是用链表实现。 但是这题有以下几点跟之前的不同:

  1. 支持从中间删除和插入,那么用数组的话,我们进行这两个操作的时候,不可避免的需要移动后面所有的元素,时间复杂度较高。

  2. 该题没有限定额定队列长度,所有没有isFull的判断,这样的话比前面就稍微容易一点。

根据上述分析,我们这里用数组来实现一下

实现代码如下:

var FrontMiddleBackQueue = function() {
    this.items = [];
};

/** 
 * @param {number} val
 * @return {void}
 */
FrontMiddleBackQueue.prototype.pushFront = function(val) {
    this.items.unshift(val);
};

/** 
 * @param {number} val
 * @return {void}
 */
FrontMiddleBackQueue.prototype.pushMiddle = function(val) {
    this.items.splice(Math.floor(this.items.length/2),0,val);
};

/** 
 * @param {number} val
 * @return {void}
 */
FrontMiddleBackQueue.prototype.pushBack = function(val) {
    this.items.push(val);
};

/**
 * @return {number}
 */
FrontMiddleBackQueue.prototype.popFront = function() {
    if(this.items.length == 0){
        return -1;
    }else{
        return this.items.shift();
    }
};

/**
 * @return {number}
 */
FrontMiddleBackQueue.prototype.popMiddle = function() {
    if(this.items.length == 0){
        return -1;
    }else{
        let middleIndex,middle;
        if(this.items.length%2){
            middleIndex = Math.floor(this.items.length/2)
        }else{
            middleIndex = Math.floor(this.items.length/2 -1 )
        }
        middle = this.items[middleIndex];
        this.items.splice(middleIndex,1)
        return middle;
    }
};

/**
 * @return {number}
 */
FrontMiddleBackQueue.prototype.popBack = function() {
    if(this.items.length == 0){
        return -1;
    }else{
        return this.items.pop();
    }
};

/**
 * Your FrontMiddleBackQueue object will be instantiated and called as such:
 * var obj = new FrontMiddleBackQueue()
 * obj.pushFront(val)
 * obj.pushMiddle(val)
 * obj.pushBack(val)
 * var param_4 = obj.popFront()
 * var param_5 = obj.popMiddle()
 * var param_6 = obj.popBack()
 */

复杂度分析

时间复杂度:O(n2),其中 n 是操作次数。

空间复杂度:O(n)