正题
设计循环双端队列
设计实现双端队列。
你的实现需要支持以下操作:
- 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
如果你还不了解队列以及循环队列,请先参考和阅读上一篇文章: 手把手带你实现JS循环队列
那么本题与上文中不同的是,它需要实现 双端 ,即需要多实现以下几个方法:
- 在
front前增加节点 - 删除
rear前节点
那么还是从构造器开始。
构建 构造器
与普通循环队列一样,没有什么不同
/**
* @param {number} k
*/
var MyCircularDeque = function(k) {
this.capatity = k
this.queue = new Array(k)
this.front = 0
this.rear = 0
};
实现 在 front 前插入节点
与普通循环队列不同,可以在 front 之前的节点插入新的节点,那么 front 节点也就随之改变。所以整体思路为,前移 front 节点,然后将 front 节点赋值。
/**
* @param {number} value
* @return {boolean}
*/
MyCircularDeque.prototype.insertFront = function(value) {
if (this.isFull()) {
return false
} else{
this.front = this.front === 0 ? this.capatity - 1 : this.front - 1
this.queue[this.front] = value
return true
}
};
实现 在 队列 尾部添加节点
和普通循环队列一样
/**
* @param {number} value
* @return {boolean}
*/
MyCircularDeque.prototype.insertLast = function(value) {
if (this.isFull()) {
return false
} else {
this.queue[this.rear] = value
this.rear = (this.rear + 1) % this.capatity
return true
}
};
实现删除 front 节点
因为普通循环队列遵循先进先出原则,所以删除front节点就和普通循环队列删除节点一样
/**
* @return {boolean}
*/
MyCircularDeque.prototype.deleteFront = function() {
if (this.isEmpty()) {
return false
} else {
this.queue[this.front] = null
this.front = (this.front + 1) % this.capatity
return true
}
};
实现删除尾部节点
移动向左 rear 指针,将移动后指针所对应的节点设置为 空即可,很容易理解,就不做图解了
/**
* @return {boolean}
*/
MyCircularDeque.prototype.deleteLast = function() {
if (this.isEmpty()) {
return false
} else {
this.rear = this.rear === 0 ? this.capatity - 1 : this.rear - 1
this.queue[this.rear] = null
return true
}
};
获取首尾节点,判断空,判断满皆和普通循环队列的实现一样
/**
* @return {number}
*/
MyCircularDeque.prototype.getFront = function() {
if (this.isEmpty()) {
return -1
} else {
return this.queue[this.front]
}
};
/**
* @return {number}
*/
MyCircularDeque.prototype.getRear = function() {
if (this.isEmpty()) {
return -1
} else {
let index = this.rear === 0 ? this.capatity - 1 : this.rear - 1
return this.queue[index]
}
};
/**
* @return {boolean}
*/
MyCircularDeque.prototype.isEmpty = function() {
return this.rear === this.front && !this.queue[this.front] && this.queue[this.front] !== 0
};
/**
* @return {boolean}
*/
MyCircularDeque.prototype.isFull = function() {
return this.rear === this.front && this.queue[this.front] !== null && this.queue[this.front] !== undefined
};
那么整合起来
完整代码:
/**
* @param {number} k
*/
var MyCircularDeque = function(k) {
this.capatity = k
this.queue = new Array(k)
this.front = 0
this.rear = 0
};
/**
* @param {number} value
* @return {boolean}
*/
MyCircularDeque.prototype.insertFront = function(value) {
if (this.isFull()) {
return false
} else{
this.front = this.front === 0 ? this.capatity - 1 : this.front - 1
this.queue[this.front] = value
return true
}
};
/**
* @param {number} value
* @return {boolean}
*/
MyCircularDeque.prototype.insertLast = function(value) {
if (this.isFull()) {
return false
} else {
this.queue[this.rear] = value
this.rear = (this.rear + 1) % this.capatity
return true
}
};
/**
* @return {boolean}
*/
MyCircularDeque.prototype.deleteFront = function() {
if (this.isEmpty()) {
return false
} else {
this.queue[this.front] = null
this.front = (this.front + 1) % this.capatity
return true
}
};
/**
* @return {boolean}
*/
MyCircularDeque.prototype.deleteLast = function() {
if (this.isEmpty()) {
return false
} else {
this.rear = this.rear === 0 ? this.capatity - 1 : this.rear - 1
this.queue[this.rear] = null
return true
}
};
/**
* @return {number}
*/
MyCircularDeque.prototype.getFront = function() {
if (this.isEmpty()) {
return -1
} else {
return this.queue[this.front]
}
};
/**
* @return {number}
*/
MyCircularDeque.prototype.getRear = function() {
if (this.isEmpty()) {
return -1
} else {
let index = this.rear === 0 ? this.capatity - 1 : this.rear - 1
return this.queue[index]
}
};
/**
* @return {boolean}
*/
MyCircularDeque.prototype.isEmpty = function() {
return this.rear === this.front && !this.queue[this.front] && this.queue[this.front] !== 0
};
/**
* @return {boolean}
*/
MyCircularDeque.prototype.isFull = function() {
return this.rear === this.front && this.queue[this.front] !== null && this.queue[this.front] !== undefined
};
/**
* Your MyCircularDeque object will be instantiated and called as such:
* var obj = new MyCircularDeque(k)
* var param_1 = obj.insertFront(value)
* var param_2 = obj.insertLast(value)
* var param_3 = obj.deleteFront()
* var param_4 = obj.deleteLast()
* var param_5 = obj.getFront()
* var param_6 = obj.getRear()
* var param_7 = obj.isEmpty()
* var param_8 = obj.isFull()
*/
如果充分理解 手把手带你实现JS循环队列 该文中的内容,那么这题其实是真的非常简单!