[路飞]LeetCode 641.设计循环双端队列

2,000 阅读2分钟

题目描述

设计实现双端队列。

你的实现需要支持以下操作:

  • MyCircularDeque(k):构造函数,双端队列的大小为k。
  • insertFront():将一个元素添加到双端队列头部。 如果操作成功返回 true。
  • insertLast():将一个元素添加到双端队列尾部。如果操作成功返回 true。
  • deleteFront():从双端队列头部删除一个元素。 如果操作成功返回 true。
  • deleteLast():从双端队列尾部删除一个元素。如果操作成功返回 true。
  • getFront():从双端队列头部获得一个元素。如果双端队列为空,返回 -1。
  • getRear():获得双端队列的最后一个元素。 如果双端队列为空,返回 -1。
  • isEmpty():检查双端队列是否为空。
  • isFull():检查双端队列是否满了。

题目思路

首先我们要借用js中的Array数组来存储队列的值(也可以自己实现一个链表来实现,这里用数组)。

其次我们要创建一个headtail,分别用来存储头尾指针

最后创建两个变量count,max来辅助操作

题目代码

在构造函数中,我们要对上面定义的变量进行初始化操作

var MyCircularDeque = function (k) {
    this.list = [];
    this.count = 0;
    this.head = 0;
    this.tail = 0;
    this.max = k;
};

其次来书写判空和判满操作

// 判空
MyCircularDeque.prototype.isEmpty = function () {
    if (this.count === 0) return true;
    return false;
};
// 判满
MyCircularDeque.prototype.isFull = function () {
    if (this.max === this.count) return true;
    return false;
};

核心点,插入顶部、插入尾部、删除顶部、删除尾部

实现插入顶部

边界条件:满员不可插入返回false

可以插入,则头部节点减一位置插入,这里有个小技巧,为了使head头指针始终范围再max之内,head - 1 后 加上max 再取余。

为list中第head-1位置的元素赋值,输出

MyCircularDeque.prototype.insertFront = function (value) {
    if (this.isFull()) return false;
    this.head = (this.head - 1 + this.max) % this.max;
    this.list[this.head] = value;
    this.count += 1;
    return true;
};

插入尾部

边界条件相同,满员返回false

插入时可以直接在尾部节点插入,因此尾部节点计算为 tail % max

处理完毕后记得调整count和max的值

MyCircularDeque.prototype.insertLast = function (value) {
    if (this.isFull()) return false;
    this.list[this.tail % this.max] = value;
    this.tail += 1;
    if (this.tail === this.max) this.tail = 0;
    this.count += 1;
    return true;
};

删除顶部

head值更新,count值更新

MyCircularDeque.prototype.deleteFront = function () {
    if (this.isEmpty()) return false;
    // this.list.splice(this.head, 1);
    this.head = (this.head + 1) % this.max;
    this.count -= 1;
    return true;
};

删除尾部

head值更新,count值更新

MyCircularDeque.prototype.deleteLast = function () {
    if (this.isEmpty()) return false;
    // this.list.splice(this.tail - 1, 1);
    this.tail = (this.tail - 1 + this.max) % this.max;
    this.count -= 1;
    return true;
};

获取顶部元素

返回head部分元素即可

MyCircularDeque.prototype.getFront = function () {
    if (this.isEmpty()) return -1;
    return this.list[this.head];
};

获取尾部元素

返回tail部分元素

MyCircularDeque.prototype.getRear = function () {
    if (this.isEmpty()) return -1;
    return this.list[(this.tail - 1 + this.max) % this.max];
};

完成

以上为设计双端循环队列全部代码实现,可以自己试试哦~~~