Skip to content

Commit 58c2190

Browse files
authored
feat: add solutions to lc problem: No.0622 (#3959)
No.0622.Design Circular Queue
1 parent 0603fe4 commit 58c2190

File tree

9 files changed

+160
-99
lines changed

9 files changed

+160
-99
lines changed

solution/0600-0699/0622.Design Circular Queue/README.md

+43-28
Original file line numberDiff line numberDiff line change
@@ -66,25 +66,41 @@ circularQueue.Rear(); &nbsp;// 返回 4</pre>
6666

6767
<!-- solution:start -->
6868

69-
### 方法一
69+
### 方法一:数组模拟
70+
71+
我们可以使用一个长度为 $k$ 的数组 $q$ 来模拟循环队列,用一个指针 $\textit{front}$ 记录队首元素的位置,初始时队列为空,而 $\textit{front}$ 为 $0$。另外,我们用一个变量 $\textit{size}$ 记录队列中元素的个数,初始时 $\textit{size}$ 为 $0$。
72+
73+
调用 `enQueue` 方法时,我们首先检查队列是否已满,即 $\textit{size} = k$,如果满了则直接返回 $\textit{false}$。否则,我们将元素插入到 $(\textit{front} + \textit{size}) \bmod k$ 的位置,然后 $\textit{size} = \textit{size} + 1$,表示队列中元素的个数增加了 $1$。最后返回 $\textit{true}$。
74+
75+
调用 `deQueue` 方法时,我们首先检查队列是否为空,即 $\textit{size} = 0$,如果为空则直接返回 $\textit{false}$。否则,我们将 $\textit{front} = (\textit{front} + 1) \bmod k$,表示队首元素出队,然后 $\textit{size} = \textit{size} - 1$,
76+
77+
调用 `Front` 方法时,我们首先检查队列是否为空,即 $\textit{size} = 0$,如果为空则返回 $-1$。否则,返回 $q[\textit{front}]$。
78+
79+
调用 `Rear` 方法时,我们首先检查队列是否为空,即 $\textit{size} = 0$,如果为空则返回 $-1$。否则,返回 $q[(\textit{front} + \textit{size} - 1) \bmod k]$。
80+
81+
调用 `isEmpty` 方法时,我们只需判断 $\textit{size} = 0$ 即可。
82+
83+
调用 `isFull` 方法时,我们只需判断 $\textit{size} = k$ 即可。
84+
85+
时间复杂度方面,以上操作的时间复杂度均为 $O(1)$。空间复杂度为 $O(k)$。
7086

7187
<!-- tabs:start -->
7288

7389
#### Python3
7490

7591
```python
7692
class MyCircularQueue:
93+
7794
def __init__(self, k: int):
7895
self.q = [0] * k
79-
self.front = 0
8096
self.size = 0
8197
self.capacity = k
98+
self.front = 0
8299

83100
def enQueue(self, value: int) -> bool:
84101
if self.isFull():
85102
return False
86-
idx = (self.front + self.size) % self.capacity
87-
self.q[idx] = value
103+
self.q[(self.front + self.size) % self.capacity] = value
88104
self.size += 1
89105
return True
90106

@@ -101,8 +117,7 @@ class MyCircularQueue:
101117
def Rear(self) -> int:
102118
if self.isEmpty():
103119
return -1
104-
idx = (self.front + self.size - 1) % self.capacity
105-
return self.q[idx]
120+
return self.q[(self.front + self.size - 1) % self.capacity]
106121

107122
def isEmpty(self) -> bool:
108123
return self.size == 0
@@ -395,64 +410,64 @@ class MyCircularQueue {
395410

396411
```rust
397412
struct MyCircularQueue {
398-
queue: Vec<i32>,
399-
left: usize,
400-
right: usize,
413+
q: Vec<i32>,
414+
size: usize,
401415
capacity: usize,
416+
front: usize,
402417
}
403418

404-
/**
405-
* `&self` means the method takes an immutable reference.
406-
* If you need a mutable reference, change it to `&mut self` instead.
407-
*/
408419
impl MyCircularQueue {
409420
fn new(k: i32) -> Self {
410-
let k = k as usize;
411-
Self {
412-
queue: vec![0; k],
413-
left: 0,
414-
right: 0,
415-
capacity: k,
421+
MyCircularQueue {
422+
q: vec![0; k as usize],
423+
size: 0,
424+
capacity: k as usize,
425+
front: 0,
416426
}
417427
}
418428

419429
fn en_queue(&mut self, value: i32) -> bool {
420430
if self.is_full() {
421431
return false;
422432
}
423-
self.queue[self.right % self.capacity] = value;
424-
self.right += 1;
433+
let rear = (self.front + self.size) % self.capacity;
434+
self.q[rear] = value;
435+
self.size += 1;
425436
true
426437
}
427438

428439
fn de_queue(&mut self) -> bool {
429440
if self.is_empty() {
430441
return false;
431442
}
432-
self.left += 1;
443+
self.front = (self.front + 1) % self.capacity;
444+
self.size -= 1;
433445
true
434446
}
435447

436448
fn front(&self) -> i32 {
437449
if self.is_empty() {
438-
return -1;
450+
-1
451+
} else {
452+
self.q[self.front]
439453
}
440-
self.queue[self.left % self.capacity]
441454
}
442455

443456
fn rear(&self) -> i32 {
444457
if self.is_empty() {
445-
return -1;
458+
-1
459+
} else {
460+
let rear = (self.front + self.size - 1) % self.capacity;
461+
self.q[rear]
446462
}
447-
self.queue[(self.right - 1) % self.capacity]
448463
}
449464

450465
fn is_empty(&self) -> bool {
451-
self.right - self.left == 0
466+
self.size == 0
452467
}
453468

454469
fn is_full(&self) -> bool {
455-
self.right - self.left == self.capacity
470+
self.size == self.capacity
456471
}
457472
}
458473
```

solution/0600-0699/0622.Design Circular Queue/README_EN.md

+43-28
Original file line numberDiff line numberDiff line change
@@ -75,25 +75,41 @@ myCircularQueue.Rear(); // return 4
7575

7676
<!-- solution:start -->
7777

78-
### Solution 1
78+
### Solution 1: Array Simulation
79+
80+
We can use an array $q$ of length $k$ to simulate a circular queue, with a pointer $\textit{front}$ to record the position of the front element. Initially, the queue is empty, and $\textit{front}$ is $0$. Additionally, we use a variable $\textit{size}$ to record the number of elements in the queue, initially $\textit{size}$ is $0$.
81+
82+
When calling the `enQueue` method, we first check if the queue is full, i.e., $\textit{size} = k$. If it is full, we return $\textit{false}$. Otherwise, we insert the element at position $(\textit{front} + \textit{size}) \bmod k$, then $\textit{size} = \textit{size} + 1$, indicating that the number of elements in the queue has increased by $1$. Finally, we return $\textit{true}$.
83+
84+
When calling the `deQueue` method, we first check if the queue is empty, i.e., $\textit{size} = 0$. If it is empty, we return $\textit{false}$. Otherwise, we set $\textit{front} = (\textit{front} + 1) \bmod k$, indicating that the front element has been dequeued, then $\textit{size} = \textit{size} - 1$.
85+
86+
When calling the `Front` method, we first check if the queue is empty, i.e., $\textit{size} = 0$. If it is empty, we return $-1$. Otherwise, we return $q[\textit{front}]$.
87+
88+
When calling the `Rear` method, we first check if the queue is empty, i.e., $\textit{size} = 0$. If it is empty, we return $-1$. Otherwise, we return $q[(\textit{front} + \textit{size} - 1) \bmod k]$.
89+
90+
When calling the `isEmpty` method, we simply check if $\textit{size} = 0$.
91+
92+
When calling the `isFull` method, we simply check if $\textit{size} = k$.
93+
94+
In terms of time complexity, the above operations all have a time complexity of $O(1)$. The space complexity is $O(k)$.
7995

8096
<!-- tabs:start -->
8197

8298
#### Python3
8399

84100
```python
85101
class MyCircularQueue:
102+
86103
def __init__(self, k: int):
87104
self.q = [0] * k
88-
self.front = 0
89105
self.size = 0
90106
self.capacity = k
107+
self.front = 0
91108

92109
def enQueue(self, value: int) -> bool:
93110
if self.isFull():
94111
return False
95-
idx = (self.front + self.size) % self.capacity
96-
self.q[idx] = value
112+
self.q[(self.front + self.size) % self.capacity] = value
97113
self.size += 1
98114
return True
99115

@@ -110,8 +126,7 @@ class MyCircularQueue:
110126
def Rear(self) -> int:
111127
if self.isEmpty():
112128
return -1
113-
idx = (self.front + self.size - 1) % self.capacity
114-
return self.q[idx]
129+
return self.q[(self.front + self.size - 1) % self.capacity]
115130

116131
def isEmpty(self) -> bool:
117132
return self.size == 0
@@ -404,64 +419,64 @@ class MyCircularQueue {
404419

405420
```rust
406421
struct MyCircularQueue {
407-
queue: Vec<i32>,
408-
left: usize,
409-
right: usize,
422+
q: Vec<i32>,
423+
size: usize,
410424
capacity: usize,
425+
front: usize,
411426
}
412427

413-
/**
414-
* `&self` means the method takes an immutable reference.
415-
* If you need a mutable reference, change it to `&mut self` instead.
416-
*/
417428
impl MyCircularQueue {
418429
fn new(k: i32) -> Self {
419-
let k = k as usize;
420-
Self {
421-
queue: vec![0; k],
422-
left: 0,
423-
right: 0,
424-
capacity: k,
430+
MyCircularQueue {
431+
q: vec![0; k as usize],
432+
size: 0,
433+
capacity: k as usize,
434+
front: 0,
425435
}
426436
}
427437

428438
fn en_queue(&mut self, value: i32) -> bool {
429439
if self.is_full() {
430440
return false;
431441
}
432-
self.queue[self.right % self.capacity] = value;
433-
self.right += 1;
442+
let rear = (self.front + self.size) % self.capacity;
443+
self.q[rear] = value;
444+
self.size += 1;
434445
true
435446
}
436447

437448
fn de_queue(&mut self) -> bool {
438449
if self.is_empty() {
439450
return false;
440451
}
441-
self.left += 1;
452+
self.front = (self.front + 1) % self.capacity;
453+
self.size -= 1;
442454
true
443455
}
444456

445457
fn front(&self) -> i32 {
446458
if self.is_empty() {
447-
return -1;
459+
-1
460+
} else {
461+
self.q[self.front]
448462
}
449-
self.queue[self.left % self.capacity]
450463
}
451464

452465
fn rear(&self) -> i32 {
453466
if self.is_empty() {
454-
return -1;
467+
-1
468+
} else {
469+
let rear = (self.front + self.size - 1) % self.capacity;
470+
self.q[rear]
455471
}
456-
self.queue[(self.right - 1) % self.capacity]
457472
}
458473

459474
fn is_empty(&self) -> bool {
460-
self.right - self.left == 0
475+
self.size == 0
461476
}
462477

463478
fn is_full(&self) -> bool {
464-
self.right - self.left == self.capacity
479+
self.size == self.capacity
465480
}
466481
}
467482
```

solution/0600-0699/0622.Design Circular Queue/Solution.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
class MyCircularQueue:
22
def __init__(self, k: int):
33
self.q = [0] * k
4-
self.front = 0
54
self.size = 0
65
self.capacity = k
6+
self.front = 0
77

88
def enQueue(self, value: int) -> bool:
99
if self.isFull():
1010
return False
11-
idx = (self.front + self.size) % self.capacity
12-
self.q[idx] = value
11+
self.q[(self.front + self.size) % self.capacity] = value
1312
self.size += 1
1413
return True
1514

@@ -26,8 +25,7 @@ def Front(self) -> int:
2625
def Rear(self) -> int:
2726
if self.isEmpty():
2827
return -1
29-
idx = (self.front + self.size - 1) % self.capacity
30-
return self.q[idx]
28+
return self.q[(self.front + self.size - 1) % self.capacity]
3129

3230
def isEmpty(self) -> bool:
3331
return self.size == 0
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,61 @@
11
struct MyCircularQueue {
2-
queue: Vec<i32>,
3-
left: usize,
4-
right: usize,
2+
q: Vec<i32>,
3+
size: usize,
54
capacity: usize,
5+
front: usize,
66
}
77

8-
/**
9-
* `&self` means the method takes an immutable reference.
10-
* If you need a mutable reference, change it to `&mut self` instead.
11-
*/
128
impl MyCircularQueue {
139
fn new(k: i32) -> Self {
14-
let k = k as usize;
15-
Self {
16-
queue: vec![0; k],
17-
left: 0,
18-
right: 0,
19-
capacity: k,
10+
MyCircularQueue {
11+
q: vec![0; k as usize],
12+
size: 0,
13+
capacity: k as usize,
14+
front: 0,
2015
}
2116
}
2217

2318
fn en_queue(&mut self, value: i32) -> bool {
2419
if self.is_full() {
2520
return false;
2621
}
27-
self.queue[self.right % self.capacity] = value;
28-
self.right += 1;
22+
let rear = (self.front + self.size) % self.capacity;
23+
self.q[rear] = value;
24+
self.size += 1;
2925
true
3026
}
3127

3228
fn de_queue(&mut self) -> bool {
3329
if self.is_empty() {
3430
return false;
3531
}
36-
self.left += 1;
32+
self.front = (self.front + 1) % self.capacity;
33+
self.size -= 1;
3734
true
3835
}
3936

4037
fn front(&self) -> i32 {
4138
if self.is_empty() {
42-
return -1;
39+
-1
40+
} else {
41+
self.q[self.front]
4342
}
44-
self.queue[self.left % self.capacity]
4543
}
4644

4745
fn rear(&self) -> i32 {
4846
if self.is_empty() {
49-
return -1;
47+
-1
48+
} else {
49+
let rear = (self.front + self.size - 1) % self.capacity;
50+
self.q[rear]
5051
}
51-
self.queue[(self.right - 1) % self.capacity]
5252
}
5353

5454
fn is_empty(&self) -> bool {
55-
self.right - self.left == 0
55+
self.size == 0
5656
}
5757

5858
fn is_full(&self) -> bool {
59-
self.right - self.left == self.capacity
59+
self.size == self.capacity
6060
}
6161
}

0 commit comments

Comments
 (0)