[路飞]_leetcode-641-设计循环双端队列

简介: leetcode-641-设计循环双端队列

网络异常,图片无法展示
|


「这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战


[题目地址][B站地址]


设计实现双端队列。


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


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


示例:


MyCircularDeque circularDeque = new MycircularDeque(3); // 设置容量大小为3
circularDeque.insertLast(1);              // 返回 true
circularDeque.insertLast(2);              // 返回 true
circularDeque.insertFront(3);             // 返回 true
circularDeque.insertFront(4);             // 已经满了,返回 false
circularDeque.getRear();          // 返回 2
circularDeque.isFull();               // 返回 true
circularDeque.deleteLast();             // 返回 true
circularDeque.insertFront(4);             // 返回 true
circularDeque.getFront();       // 返回 4
复制代码


提示:


  • 所有值的范围为 [1, 1000]
  • 操作次数的范围为 [1, 1000]
  • 请不要使用内置的双端队列库。


本题只是在上文题目《leetcode-622-设计循环队列》的基础上加了一丢丢🤏的难度

首先我们回顾一下循环队列的性质


循环队列其实就像是一个有固定座位数量的餐桌,来吃饭的人依次坐好,当坐满人之后,新来的人坐不下只能离开或者在一旁排队


当先来的人吃饱离开后,此时空出座位,后续的人就可以坐下吃饭了(这里严格遵循先到先吃饱离开的规则😃)


过程如下:


网络异常,图片无法展示
|


那么双端队列依然类似于一个有固定座位数量的餐桌,只不过和循环队列稍有不同。

依然以餐桌为例:


网络异常,图片无法展示
|


理解了循环双端队列的性质后,如何设计该数据结构呢?


思路如下:


  1. 首先构造函数中,根据传入值记录队列长度 max。接下来创建空数组 queue 存储队列中的值,并创建 headend 指针初初始化指向 -1,创建 size 属性初始化为 0
  2. 队首插入操作中,判断队列是否已满,如果队列已满,返回false。否则判断 head===-1,如果为真,说明队列是初始化状态,此时新插入的值一定在下标0位置,将 head = 0 end = 0。否则需要让 head 指针向前走一步,这里要判断 head 指针是否在下标 0 位置,如果在下标 0 位置,则需要将 head 指针调整到数组末尾。最后将 value 插入到 head 指针所在位置即可,this.size++
  3. 队尾插入操作中,判断队列是否已满,如果队列已满,返回false。否则判断 end===-1,如果为真,说明队列是初始化状态,此时新插入的值一定在下标0位置,将 head = 0 end = 0。否则需要让 end 指针向后走一步,这里要判断 end 指针是否在数组末尾位置,如果在数组末尾位置,则需要将 end 指针调整到下标 0 位置。最后将 value 插入到 end 指针所在位置即可,this.size++
  4. 删除队首元素操作首先需要判断队列是否为空,如果为空,返回 false。否则只需要调整 head 指针向后走一步即可。同样需要判断此时 head 指针是否在数组末尾,如果是,则 head = 0。最后不要忘记 this.size--

5.删除队尾元素操作首先需要判断队列是否为空,如果为空,返回 false。否则只需要

调整 end 指针向前走一步即可。这里需要判断 end 指针是否在下标 0 位置,如果是,需要将 end 指针调整到数组末尾。最后不要忘记 this.size-- 6. 获取队首元素首先判断队列是否为空,如果为空,返回 -1,否则返回 this.queue[this.head] 即可 7. 获取队尾元素首先判断队列是否为空,如果为空,返回 -1,否则返回

this.queue[this.end] 即可 8. 判断队列是否为空只需要判断 this.size === 0 即可 9. 判断队列是否已满只需要判断 this.size === this.max 即可


以本题示例为例,以上过程如下:


网络异常,图片无法展示
|

代码如下:


var MyCircularDeque = function(k) {
  this.max = k;
  this.queue = [];
  this.head = -1;
  this.end = -1;
  this.size = 0;
};
/** 
 * @param {number} value
 * @return {boolean}
 */
MyCircularDeque.prototype.insertFront = function(value) {
  if(this.isFull()) return false;
  if(this.head===-1){
    this.head = 0;
    this.end = 0;
  }else if(this.head === 0){
    this.head = this.max-1
  }else{
    this.head--
  }
  this.size++;
  this.queue[this.head] = value;
  return true;
};
/** 
 * @param {number} value
 * @return {boolean}
 */
MyCircularDeque.prototype.insertLast = function(value) {
  if(this.isFull()) return false;
  if(this.end===-1){
    this.head = 0;
    this.end = 0;
  }else if(this.end === this.max-1){
    this.end = 0
  }else{
    this.end++
  }
  this.size++;
  this.queue[this.end] = value;
  return true;
};
/**
 * @return {boolean}
 */
MyCircularDeque.prototype.deleteFront = function() {
  if(this.isEmpty()) return false;
  if(this.head === this.max-1){
    this.head = 0
  }else{
    this.head++
  }
  this.size--;
  return true;
};
/**
 * @return {boolean}
 */
MyCircularDeque.prototype.deleteLast = function() {
  if(this.isEmpty()) return false;
  if(this.end === 0){
    this.end = this.max-1;
  }else{
    this.end--;
  }
  this.size--;
  return true;
};
/**
 * @return {number}
 */
MyCircularDeque.prototype.getFront = function() {
  if(this.isEmpty()) return -1;
  return this.queue[this.head]
};
/**
 * @return {number}
 */
MyCircularDeque.prototype.getRear = function() {
  if(this.isEmpty()) return -1;
  return this.queue[this.end]
};
/**
 * @return {boolean}
 */
MyCircularDeque.prototype.isEmpty = function() {
  return this.size === 0
};
/**
 * @return {boolean}
 */
MyCircularDeque.prototype.isFull = function() {
  return this.size === this.max
};
复制代码


至此我们就完成了 leetcode-641-设计循环双端队列


如有任何问题或建议,欢迎留言讨论!

相关文章
|
3月前
【LeetCode 24】225.用队列实现栈
【LeetCode 24】225.用队列实现栈
20 0
|
3月前
|
算法
【LeetCode 23】232.用栈实现队列
【LeetCode 23】232.用栈实现队列
28 0
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 09. 用两个栈实现队列
使用两个栈实现队列的Python解决方案,包括初始化两个栈、实现在队列尾部添加整数的appendTail方法和在队列头部删除整数的deleteHead方法,以及相应的示例操作。
44 2
|
5月前
|
Python
【Leetcode刷题Python】641.循环双端队列
文章介绍了如何实现一个循环双端队列,包括其操作如插入、删除、获取队首和队尾元素,以及检查队列是否为空或已满,并提供了Python语言的实现代码。
28 0
|
5月前
|
Python
【Leetcode刷题Python】232. 用栈实现队列
如何使用Python语言通过两个栈来实现队列的所有基本操作,包括入队(push)、出队(pop)、查看队首元素(peek)和判断队列是否为空(empty),并提供了相应的代码实现。
26 0
|
7月前
|
存储 算法 Python
二刷力扣--栈和队列
二刷力扣--栈和队列
|
7月前
|
容器
【LeetCode刷题】栈和队列题目练习~
【LeetCode刷题】栈和队列题目练习~
|
8月前
|
机器学习/深度学习 存储 算法
数据结构与算法⑨(第三章_下)队列的概念和实现(力扣:225+232+622)(下)
数据结构与算法⑨(第三章_下)队列的概念和实现(力扣:225+232+622)
30 0
|
8月前
|
算法 前端开发 C语言
数据结构与算法⑨(第三章_下)队列的概念和实现(力扣:225+232+622)(上)
数据结构与算法⑨(第三章_下)队列的概念和实现(力扣:225+232+622)
50 0
|
8月前
|
C语言
Leetcode每日一题——“用栈实现队列”
Leetcode每日一题——“用栈实现队列”