Skip to content

Commit

Permalink
feat: add solutions to lc problem: No.0622
Browse files Browse the repository at this point in the history
No.0622.Design Circular Queue
  • Loading branch information
yanglbme committed Jan 16, 2025
1 parent 0603fe4 commit 0a90493
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 99 deletions.
71 changes: 43 additions & 28 deletions solution/0600-0699/0622.Design Circular Queue/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,25 +66,41 @@ circularQueue.Rear(); &nbsp;// 返回 4</pre>

<!-- solution:start -->

### 方法一
### 方法一:数组模拟

我们可以使用一个长度为 $k$ 的数组 $q$ 来模拟循环队列,用一个指针 $\textit{front}$ 记录队首元素的位置,初始时队列为空,而 $\textit{front}$ 为 $0$。另外,我们用一个变量 $\textit{size}$ 记录队列中元素的个数,初始时 $\textit{size}$ 为 $0$。

调用 `enQueue` 方法时,我们首先检查队列是否已满,即 $\textit{size} = k$,如果满了则直接返回 $\textit{false}$。否则,我们将元素插入到 $(\textit{front} + \textit{size}) \bmod k$ 的位置,然后 $\textit{size} = \textit{size} + 1$,表示队列中元素的个数增加了 $1$。最后返回 $\textit{true}$。

调用 `deQueue` 方法时,我们首先检查队列是否为空,即 $\textit{size} = 0$,如果为空则直接返回 $\textit{false}$。否则,我们将 $\textit{front} = (\textit{front} + 1) \bmod k$,表示队首元素出队,然后 $\textit{size} = \textit{size} - 1$,

调用 `Front` 方法时,我们首先检查队列是否为空,即 $\textit{size} = 0$,如果为空则返回 $-1$。否则,返回 $q[\textit{front}]$。

调用 `Rear` 方法时,我们首先检查队列是否为空,即 $\textit{size} = 0$,如果为空则返回 $-1$。否则,返回 $q[(\textit{front} + \textit{size} - 1) \bmod k]$。

调用 `isEmpty` 方法时,我们只需判断 $\textit{size} = 0$ 即可。

调用 `isFull` 方法时,我们只需判断 $\textit{size} = k$ 即可。

时间复杂度方面,以上操作的时间复杂度均为 $O(1)$。空间复杂度为 $O(k)$。

<!-- tabs:start -->

#### Python3

```python
class MyCircularQueue:

def __init__(self, k: int):
self.q = [0] * k
self.front = 0
self.size = 0
self.capacity = k
self.front = 0

def enQueue(self, value: int) -> bool:
if self.isFull():
return False
idx = (self.front + self.size) % self.capacity
self.q[idx] = value
self.q[(self.front + self.size) % self.capacity] = value
self.size += 1
return True

Expand All @@ -101,8 +117,7 @@ class MyCircularQueue:
def Rear(self) -> int:
if self.isEmpty():
return -1
idx = (self.front + self.size - 1) % self.capacity
return self.q[idx]
return self.q[(self.front + self.size - 1) % self.capacity]

def isEmpty(self) -> bool:
return self.size == 0
Expand Down Expand Up @@ -395,64 +410,64 @@ class MyCircularQueue {

```rust
struct MyCircularQueue {
queue: Vec<i32>,
left: usize,
right: usize,
q: Vec<i32>,
size: usize,
capacity: usize,
front: usize,
}

/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl MyCircularQueue {
fn new(k: i32) -> Self {
let k = k as usize;
Self {
queue: vec![0; k],
left: 0,
right: 0,
capacity: k,
MyCircularQueue {
q: vec![0; k as usize],
size: 0,
capacity: k as usize,
front: 0,
}
}

fn en_queue(&mut self, value: i32) -> bool {
if self.is_full() {
return false;
}
self.queue[self.right % self.capacity] = value;
self.right += 1;
let rear = (self.front + self.size) % self.capacity;
self.q[rear] = value;
self.size += 1;
true
}

fn de_queue(&mut self) -> bool {
if self.is_empty() {
return false;
}
self.left += 1;
self.front = (self.front + 1) % self.capacity;
self.size -= 1;
true
}

fn front(&self) -> i32 {
if self.is_empty() {
return -1;
-1
} else {
self.q[self.front]
}
self.queue[self.left % self.capacity]
}

fn rear(&self) -> i32 {
if self.is_empty() {
return -1;
-1
} else {
let rear = (self.front + self.size - 1) % self.capacity;
self.q[rear]
}
self.queue[(self.right - 1) % self.capacity]
}

fn is_empty(&self) -> bool {
self.right - self.left == 0
self.size == 0
}

fn is_full(&self) -> bool {
self.right - self.left == self.capacity
self.size == self.capacity
}
}
```
Expand Down
71 changes: 43 additions & 28 deletions solution/0600-0699/0622.Design Circular Queue/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,25 +75,41 @@ myCircularQueue.Rear(); // return 4

<!-- solution:start -->

### Solution 1
### Solution 1: Array Simulation

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$.

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}$.

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$.

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}]$.

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]$.

When calling the `isEmpty` method, we simply check if $\textit{size} = 0$.

When calling the `isFull` method, we simply check if $\textit{size} = k$.

In terms of time complexity, the above operations all have a time complexity of $O(1)$. The space complexity is $O(k)$.

<!-- tabs:start -->

#### Python3

```python
class MyCircularQueue:

def __init__(self, k: int):
self.q = [0] * k
self.front = 0
self.size = 0
self.capacity = k
self.front = 0

def enQueue(self, value: int) -> bool:
if self.isFull():
return False
idx = (self.front + self.size) % self.capacity
self.q[idx] = value
self.q[(self.front + self.size) % self.capacity] = value
self.size += 1
return True

Expand All @@ -110,8 +126,7 @@ class MyCircularQueue:
def Rear(self) -> int:
if self.isEmpty():
return -1
idx = (self.front + self.size - 1) % self.capacity
return self.q[idx]
return self.q[(self.front + self.size - 1) % self.capacity]

def isEmpty(self) -> bool:
return self.size == 0
Expand Down Expand Up @@ -404,64 +419,64 @@ class MyCircularQueue {

```rust
struct MyCircularQueue {
queue: Vec<i32>,
left: usize,
right: usize,
q: Vec<i32>,
size: usize,
capacity: usize,
front: usize,
}

/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl MyCircularQueue {
fn new(k: i32) -> Self {
let k = k as usize;
Self {
queue: vec![0; k],
left: 0,
right: 0,
capacity: k,
MyCircularQueue {
q: vec![0; k as usize],
size: 0,
capacity: k as usize,
front: 0,
}
}

fn en_queue(&mut self, value: i32) -> bool {
if self.is_full() {
return false;
}
self.queue[self.right % self.capacity] = value;
self.right += 1;
let rear = (self.front + self.size) % self.capacity;
self.q[rear] = value;
self.size += 1;
true
}

fn de_queue(&mut self) -> bool {
if self.is_empty() {
return false;
}
self.left += 1;
self.front = (self.front + 1) % self.capacity;
self.size -= 1;
true
}

fn front(&self) -> i32 {
if self.is_empty() {
return -1;
-1
} else {
self.q[self.front]
}
self.queue[self.left % self.capacity]
}

fn rear(&self) -> i32 {
if self.is_empty() {
return -1;
-1
} else {
let rear = (self.front + self.size - 1) % self.capacity;
self.q[rear]
}
self.queue[(self.right - 1) % self.capacity]
}

fn is_empty(&self) -> bool {
self.right - self.left == 0
self.size == 0
}

fn is_full(&self) -> bool {
self.right - self.left == self.capacity
self.size == self.capacity
}
}
```
Expand Down
8 changes: 3 additions & 5 deletions solution/0600-0699/0622.Design Circular Queue/Solution.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
class MyCircularQueue:
def __init__(self, k: int):
self.q = [0] * k
self.front = 0
self.size = 0
self.capacity = k
self.front = 0

def enQueue(self, value: int) -> bool:
if self.isFull():
return False
idx = (self.front + self.size) % self.capacity
self.q[idx] = value
self.q[(self.front + self.size) % self.capacity] = value
self.size += 1
return True

Expand All @@ -26,8 +25,7 @@ def Front(self) -> int:
def Rear(self) -> int:
if self.isEmpty():
return -1
idx = (self.front + self.size - 1) % self.capacity
return self.q[idx]
return self.q[(self.front + self.size - 1) % self.capacity]

def isEmpty(self) -> bool:
return self.size == 0
Expand Down
44 changes: 22 additions & 22 deletions solution/0600-0699/0622.Design Circular Queue/Solution.rs
Original file line number Diff line number Diff line change
@@ -1,61 +1,61 @@
struct MyCircularQueue {
queue: Vec<i32>,
left: usize,
right: usize,
q: Vec<i32>,
size: usize,
capacity: usize,
front: usize,
}

/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl MyCircularQueue {
fn new(k: i32) -> Self {
let k = k as usize;
Self {
queue: vec![0; k],
left: 0,
right: 0,
capacity: k,
MyCircularQueue {
q: vec![0; k as usize],
size: 0,
capacity: k as usize,
front: 0,
}
}

fn en_queue(&mut self, value: i32) -> bool {
if self.is_full() {
return false;
}
self.queue[self.right % self.capacity] = value;
self.right += 1;
let rear = (self.front + self.size) % self.capacity;
self.q[rear] = value;
self.size += 1;
true
}

fn de_queue(&mut self) -> bool {
if self.is_empty() {
return false;
}
self.left += 1;
self.front = (self.front + 1) % self.capacity;
self.size -= 1;
true
}

fn front(&self) -> i32 {
if self.is_empty() {
return -1;
-1
} else {
self.q[self.front]
}
self.queue[self.left % self.capacity]
}

fn rear(&self) -> i32 {
if self.is_empty() {
return -1;
-1
} else {
let rear = (self.front + self.size - 1) % self.capacity;
self.q[rear]
}
self.queue[(self.right - 1) % self.capacity]
}

fn is_empty(&self) -> bool {
self.right - self.left == 0
self.size == 0
}

fn is_full(&self) -> bool {
self.right - self.left == self.capacity
self.size == self.capacity
}
}
Loading

0 comments on commit 0a90493

Please sign in to comment.