[路飞]1670. 设计前中后队列

118 阅读2分钟

题目描述

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

分析

输入:并没有要求数组的 capacity
输出:队列的实例,有题目要求的方法

解题思路

本题我们仍然用数组来作为我们存储数据的数据结构,因为不论是前后的增,删,还是从中间插入删除,数组都有支持的方法。

我们依次实现要求的方法,然后从题看下代码~

pushFront: 我们用数组的 unshift 进行实现

pushMiddle, popMiddle,这两个我们放在一起看: 我们那一个数组举例子,[1, 2, 3,4],对于这么一个数组,我们需要按照题目要求去插入一个 666,应该怎么办呢?
实际上需要在 2 的后面加上他,最终形成 [1, 2, 666, 3, 4],这是因为题目告诉我们,在有两个中间位置的时候,取左边的。所以这个位置就是 arr.length >>> 1
那删除的情况呢?
我们要删除 2,需要删除的是 arr.length - 1 >>> 1,也就是 3 / 2, 向下取整,得到 1
这两个是否“减1”,需要特别地注意 ⚠️ 一把。

pushBack: 我们用数组的 push 实现

popFront:我们用数组的 shift 实现

popBack: 我们用数组的 pop 实现

代码

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

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

/**
 * @param {number} val
 * @return {void}
 */
FrontMiddleBackQueue.prototype.pushMiddle = function (val) {
  this.queue.splice(this.queue.length >>> 1, 0, val)
}

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

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

  return this.queue.shift()
}

/**
 * @return {number}
 */
FrontMiddleBackQueue.prototype.popMiddle = function () {
  if (this.queue.length === 0) return -1

  return this.queue.splice((this.queue.length - 1) >>> 1, 1)
}

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

  return this.queue.pop()
}

复杂度

时间:O(1),均为常量级别的复杂度 空间:O(N),需要用数组存储所有的数据