趣味算法题

越刷越上头的趣味算法题
帅旋
关注
充电
IT宅站长,技术博主,架构师,全网id:arthinking。

设计一个设计循环双端队列

发布于 2024-05-14 | 更新于 2024-08-21

题目:641. 设计循环双端队列[1]

如果您已经有思路了,或者是N刷了,可以先自己写一遍。

题目分析

循环双端队列(Circular Deque)是一种特殊类型的数据结构,它结合了队列和双端队列的特性,并在此基础上添加了循环的特点。这意味着队列的末尾被视为与队列的开头相连,形成一个闭环。

设计一个循环双端队列(Circular Deque),需要实现以下操作:

  1. MyCircularDeque(int k):构造函数,双端队列的最大大小为 k。
  2. insertFront(int value):在双端队列的前端插入一个元素,成功返回 true,如果队列满了返回 false
  3. insertLast(int value):在双端队列的后端插入一个元素,成功返回 true,如果队列满了返回 false
  4. deleteFront():从双端队列的前端删除一个元素,成功返回 true,如果队列为空返回 false
  5. deleteLast():从双端队列的后端删除一个元素,成功返回 true,如果队列为空返回 false
  6. getFront():从双端队列的前端获取一个元素,如果双端队列为空,返回 -1
  7. getRear():从双端队列的后端获取一个元素,如果双端队列为空,返回 -1
  8. isEmpty():检查双端队列是否为空。
  9. 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)); // 返回 true
System.out.println(circularDeque.insertLast(2)); // 返回 true
System.out.println(circularDeque.insertFront(3)); // 返回 true
System.out.println(circularDeque.insertFront(4)); // 返回 false, 因为队列满了
System.out.println(circularDeque.getRear()); // 返回 2
System.out

可否使用双向链表实现循环双端队列?

基于双向链表的实现方式对于循环双端队列是完全可行的,尤其适合于元素大小动态变化的场景。

如果使用双向链表实现循环双端队列,有以下几个优点和潜在的注意事项:

优点

  1. 动态大小调整:与基于固定大小数组的实现相比,双向链表实现的队列不需要预先定义数组的大小,可以动态地增加和减少节点。
  2. 高效的插入和删除:在链表的头部和尾部插入或删除节点的操作时间复杂度为 𝑂(1)O(1),因为不需要移动其他元素。

注意事项

  1. 内存使用:每个元素都需要额外的空间来存储前后节点的引用,这比数组实现更耗费内存。
  2. 性能问题:尽管节点的插入和删除是常数时间,但是由于内存中的节点可能不连续,这可能会影响缓存的利用率,进而影响性能。

References


  1. 641. 设计循环双端队列 ↩︎

本文作者: 帅旋

本文链接: https://www.itzhai.com/columns/algorithm/design-circular-deque.html

版权声明: 版权归作者所有,未经许可不得转载,侵权必究!联系作者请加公众号。

×
IT宅

关注公众号及时获取网站内容更新。

请帅旋喝一杯咖啡

咖啡=电量,给帅旋充杯咖啡,他会满电写代码!

IT宅

关注公众号及时获取网站内容更新。