题目:641. 设计循环双端队列
如果您已经有思路了,或者是N刷了,可以先自己写一遍。
题目分析
循环双端队列(Circular Deque)是一种特殊类型的数据结构,它结合了队列和双端队列的特性,并在此基础上添加了循环的特点。这意味着队列的末尾被视为与队列的开头相连,形成一个闭环。
设计一个循环双端队列(Circular Deque),需要实现以下操作:
MyCircularDeque(int k)
:构造函数,双端队列的最大大小为 k。
insertFront(int value)
:在双端队列的前端插入一个元素,成功返回 true
,如果队列满了返回 false
。
insertLast(int value)
:在双端队列的后端插入一个元素,成功返回 true
,如果队列满了返回 false
。
deleteFront()
:从双端队列的前端删除一个元素,成功返回 true
,如果队列为空返回 false
。
deleteLast()
:从双端队列的后端删除一个元素,成功返回 true
,如果队列为空返回 false
。
getFront()
:从双端队列的前端获取一个元素,如果双端队列为空,返回 -1
。
getRear()
:从双端队列的后端获取一个元素,如果双端队列为空,返回 -1
。
isEmpty()
:检查双端队列是否为空。
isFull()
:检查双端队列是否满了。
解题思路
设计一个循环双端队列可以用Java的数组来实现。这种数据结构需要支持在队列的前端和后端进行插入和删除操作。
Java解法
下面是使用Java语言的解法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| class MyCircularDeque { private int[] data; private int head; private int tail; private int size; private int capacity;
public MyCircularDeque(int k) { capacity = k; data = new int[k]; head = -1; tail = -1; size = 0; }
public boolean insertFront(int value) { if (isFull()) { return false; } if (isEmpty()) { head = 0; tail = 0; } else { head = (head - 1 + capacity) % capacity; } data[head] = value; size++; return true; }
public boolean insertLast(int value) { if (isFull()) { return false; } if (isEmpty()) { head = 0; tail = 0; } else { tail = (tail + 1) % capacity; } data[tail] = value; size++; return true; }
public boolean deleteFront() { if (isEmpty()) { return false; } if (head == tail) { head = -1; tail = -1; } else { head = (head + 1) % capacity; } size--; return true; }
public boolean deleteLast() { if (isEmpty()) { return false; } if (head == tail) { head = -1; tail = -1; } else { tail = (tail - 1 + capacity) % capacity; } size--; return true; }
public int getFront() { if (isEmpty()) { return -1; } return data[head]; }
public int getRear() { if (isEmpty()) { return -1; } return data[tail]; }
public boolean isEmpty() { return size == 0; }
public boolean isFull() { return size == capacity; }
public static void main(String[] args) { MyCircularDeque circularDeque = new MyCircularDeque(3); System.out.println(circularDeque.insertLast(1)); System.out.println(circularDeque.insertLast(2)); System.out.println(circularDeque.insertFront(3)); System.out.println(circularDeque.insertFront(4)); System.out.println(circularDeque.getRear()); System.out
|
可否使用双向链表实现循环双端队列?
基于双向链表的实现方式对于循环双端队列是完全可行的,尤其适合于元素大小动态变化的场景。
如果使用双向链表实现循环双端队列,有以下几个优点和潜在的注意事项:
优点
- 动态大小调整:与基于固定大小数组的实现相比,双向链表实现的队列不需要预先定义数组的大小,可以动态地增加和减少节点。
- 高效的插入和删除:在链表的头部和尾部插入或删除节点的操作时间复杂度为 𝑂(1)O(1),因为不需要移动其他元素。
注意事项
- 内存使用:每个元素都需要额外的空间来存储前后节点的引用,这比数组实现更耗费内存。
- 性能问题:尽管节点的插入和删除是常数时间,但是由于内存中的节点可能不连续,这可能会影响缓存的利用率,进而影响性能。
References