题目
设计实现双端队列。
你的实现需要支持以下操作:
- 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();
提示:
- 所有值的范围为 [1, 1000]
- 操作次数的范围为 [1, 1000]
- 请不要使用内置的双端队列库。
想法一:使用Python强大的列表
不得不说Python的队列真的是集大成者,一个列表就能实现栈、队列等操作,只需要稍加包装即可,代码如下:
算法实现
class MyCircularDeque:
def __init__(self, k: int):
self.maxl = k
self.deque = []
def insertFront(self, value: int) -> bool:
if len(self.deque) == self.maxl:
return False
self.deque.insert(0, value)
return True
def insertLast(self, value: int) -> bool:
if len(self.deque) == self.maxl:
return False
self.deque.append(value)
return True
def deleteFront(self) -> bool:
if not self.deque:
return False
self.deque.pop(0)
return True
def deleteLast(self) -> bool:
if not self.deque:
return False
self.deque.pop()
return True
def getFront(self) -> int:
if not self.deque:
return -1
return self.deque[0]
def getRear(self) -> int:
if not self.deque:
return -1
return self.deque[-1]
def isEmpty(self) -> bool:
return not self.deque
def isFull(self) -> bool:
return len(self.deque) == self.maxl
执行结果
执行结果 : 通过
执行用时 : 72 ms, 在所有 Python3 提交中击败了87.38%的用户
内存消耗 : 13.9 MB, 在所有 Python3 提交中击败了8.82%的用户
想法二:自建
算法实现
class MyCircularDeque:
def __init__(self, k: int):
self.maxlen = k
self.l = 0
self.deque = [0] * k
self.pHead = 0
self.pRear = 0
def insertFront(self, value: int) -> bool:
if self.l == self.maxlen:
return False
if self.l:
self.pHead = self.pHead - 1 if self.pHead > 0 else self.maxlen - 1
self.deque[self.pHead] = value
self.l += 1
return True
def insertLast(self, value: int) -> bool:
if self.l == self.maxlen:
return False
if self.l:
self.pRear = self.pRear + 1 if self.pRear < self.maxlen - 1 else 0
self.deque[self.pRear] = value
self.l += 1
return True
def deleteFront(self) -> bool:
if not self.l:
return False
if self.l != 1:
self.pHead = self.pHead + 1 if self.pHead < self.maxlen - 1 else 0
self.l -= 1
return True
def deleteLast(self) -> bool:
if not self.l:
return False
if self.l != 1:
self.pRear = self.pRear - 1 if self.pRear > 0 else self.maxlen - 1
self.l -= 1
return True
def getFront(self) -> int:
if not self.l:
return -1
return self.deque[self.pHead]
def getRear(self) -> int:
if not self.l:
return -1
return self.deque[self.pRear]
def isEmpty(self) -> bool:
return not self.l
def isFull(self) -> bool:
return self.l == self.maxlen
执行结果
小结
循环双端队列一种方法是利用Python的列表,做法比较简单粗暴,但是效果也很不错;另一种是自己造轮子,对循环队列的代码稍加改进,有些要注意的小细节,之前让我修改了很多次:
- 在插入元素时要考虑没有元素的情况与有元素的情况是不一样的,没有元素的情况头尾指针不需要移动原地修改,有元素的情况要移动。同时还要考虑边界情况。
- 在删除元素时容易忘记考虑边界情况。
两种效率感觉差不多,但是还是利用已有的轮子比较舒服,因为不用考虑边界情况等,再次感叹 Python大法好!