vault backup: 2026-05-14 23:42:03
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
$filepath = 'D:\Obsidian\leetcode-go\basic\队列实现.md'
|
||||||
|
$content = [System.IO.File]::ReadAllText($filepath, [System.Text.Encoding]::UTF8)
|
||||||
|
$lines = $content -split "`n"
|
||||||
|
|
||||||
|
# Table 1: replace lines at indices 102-112 (0-based)
|
||||||
|
$table1 = @(
|
||||||
|
'| 操作 | 状态 head → tail | 实际存储 [0..4] | head | tail | len | cap |',
|
||||||
|
'|------|-----------------|-----------------|------|------|-----|-----|',
|
||||||
|
'| 初始 | — | ───── | 0 | 0 | 0 | 5 |',
|
||||||
|
'| Inqueue(1) | head→tail | 1──── | 0 | 1 | 1 | 5 |',
|
||||||
|
'| Inqueue(2) | head→··tail· | 12─── | 0 | 2 | 2 | 5 |',
|
||||||
|
'| Inqueue(3) | head→···tail· | 123── | 0 | 3 | 3 | 5 |',
|
||||||
|
'| Dequeue() | ·tail→···tail· | ─23── | 1 | 3 | 2 | 5 |',
|
||||||
|
'| Dequeue() | ···tail→··tail· | ──3── | 2 | 3 | 1 | 5 |',
|
||||||
|
'| Inqueue(4) | head→···tail→ | ──34─ | 2 | 4 | 2 | 5 |',
|
||||||
|
'| Inqueue(5) | head→····tail→ | ──345 | 2 | 5 | 3 | 5 |',
|
||||||
|
'| Dequeue() | ···tail→···tail | ───45 | 3 | 5 | 2 | 5 |'
|
||||||
|
)
|
||||||
|
|
||||||
|
$newLines = @()
|
||||||
|
for ($idx = 0; $idx -lt $lines.Length; $idx++) {
|
||||||
|
if ($idx -ge 102 -and $idx -le 112) {
|
||||||
|
# Skip these lines (being replaced by table1)
|
||||||
|
continue
|
||||||
|
} elseif ($idx -eq 102) {
|
||||||
|
foreach ($line in $table1) {
|
||||||
|
$newLines += $line
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$newLines += $lines[$idx]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.IO.File]::WriteAllText($filepath, ($newLines -join "`n"), [System.Text.Encoding]::UTF8)
|
||||||
|
Write-Output "Table 1 fixed. Total lines: $($newLines.Count)"
|
||||||
+109
@@ -0,0 +1,109 @@
|
|||||||
|
---
|
||||||
|
tags: ["Go", "基础数据结构", "队列"]
|
||||||
|
create time: 2026-05-14 18:00
|
||||||
|
---
|
||||||
|
|
||||||
|
# 队列(Queue)
|
||||||
|
|
||||||
|
## 什么时候用
|
||||||
|
|
||||||
|
看到 **BFS、层序遍历、滑动窗口** → 用队列。
|
||||||
|
FIFO:先进去的先出来。类比排队打饭,先到先得。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 模板
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Queue struct {
|
||||||
|
data []int // 底层用一个 slice 存数据
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push 入队:往末尾追加一个元素
|
||||||
|
func (q *Queue) Push(v int) {
|
||||||
|
q.data = append(q.data, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pop 出队:取出第一个元素,再把第一个元素切掉
|
||||||
|
func (q *Queue) Pop() int {
|
||||||
|
v := q.data[0] // 先拿到值
|
||||||
|
q.data = q.data[1:] // 再切除第一个位置
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Front 看队首元素但不取走
|
||||||
|
func (q *Queue) Front() int {
|
||||||
|
return q.data[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty 判断是否为空
|
||||||
|
func (q *Queue) Empty() bool {
|
||||||
|
return len(q.data) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len 当前有多少个元素
|
||||||
|
func (q *Queue) Len() int {
|
||||||
|
return len(q.data)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**核心思路就两件事:** `append` 往尾巴加,`data[1:]` 从头部踢。简单粗暴有效。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## BFS 用法
|
||||||
|
|
||||||
|
BFS 的精髓就是:**把当前层的节点全部取出,然后把它们的子节点全部放进队列等下一轮处理。**
|
||||||
|
|
||||||
|
```go
|
||||||
|
q := &Queue{}
|
||||||
|
q.Push(root) // 先把根节点放进去
|
||||||
|
|
||||||
|
for !q.Empty() { // 队列不空就一直处理
|
||||||
|
node := q.Front() // 看队首
|
||||||
|
q.Pop() // 弹出队首
|
||||||
|
|
||||||
|
if node.Left != nil {
|
||||||
|
q.Push(node.Left) // 左子节点入队
|
||||||
|
}
|
||||||
|
if node.Right != nil {
|
||||||
|
q.Push(node.Right) // 右子节点入队
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
如果要**按层**输出(比如 LeetCode 102),在外层循环里记一下当前层有几个节点,内层只处理这么多:
|
||||||
|
|
||||||
|
```go
|
||||||
|
for !q.Empty() {
|
||||||
|
size := q.Len() // 当前层有几个节点
|
||||||
|
level := []int{} // 存这一层的结果
|
||||||
|
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
node, _ := q.Pop()
|
||||||
|
level = append(level, node.Val)
|
||||||
|
|
||||||
|
if node.Left != nil {
|
||||||
|
q.Push(node.Left)
|
||||||
|
}
|
||||||
|
if node.Right != nil {
|
||||||
|
q.Push(node.Right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = append(result, level) // 这一层处理完了,存起来
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!tip] 🔑 关键点
|
||||||
|
>
|
||||||
|
> `size := q.Len()` 这行必须在内层循环前执行。因为内层会不断 Push 新节点进入队列,如果不提前记录当前层的大小,就会无限循环下去。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 对应题目
|
||||||
|
|
||||||
|
| 难度 | 题目 | 要点 |
|
||||||
|
|------|------|------|
|
||||||
|
| ⭐⭐ | [[102.binary-tree-level-order-traversal]] | 层序遍历标准写法 |
|
||||||
|
| ⭐⭐ | [[127.word-ladder]] | BFS 求最短路径 |
|
||||||
|
| ⭐⭐⭐ | [[239.sliding-window-maximum]] | 单调队列(进阶) |
|
||||||
+3
-4
@@ -562,10 +562,9 @@ func rotateLeft(nums []int, k int) {
|
|||||||
}
|
}
|
||||||
k %= n
|
k %= n
|
||||||
|
|
||||||
reverse(nums, 0, k-1) // Step 1: 反转前 k 个 [5,6,7, 1,2,3,4] → [7,6,5, 1,2,3,4]
|
reverse(nums, 0, k-1) // Step 1: 反转前 k 个 [3,2,1, 4,5,6,7]
|
||||||
reverse(nums, k, n-1) // Step 2: 反转剩余部分 [7,6,5, 1,2,3,4] → [7,6,5, 4,3,2,1]
|
reverse(nums, k, n-1) // Step 2: 反转剩余部分 [3,2,1, 7,6,5,4]
|
||||||
reverse(nums, 0, n-1) // Step 3: 整体反转 [7,6,5, 4,3,2,1] → [1,2,3,4,5,6,7] ← 恢复!
|
reverse(nums, 0, n-1) // Step 3: 整体反转 [4,5,6,7, 1,2,3] ← [1,2,3,4,5,6,7] 左旋 3 位的结果
|
||||||
// 上面用的是 k=3 的示例,实际上对 [1,2,3,4,5,6,7] 左旋 3 位的结果是 [4,5,6,7,1,2,3]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// rotateCyclicLeft 使用循环替换实现向左轮转数组。
|
// rotateCyclicLeft 使用循环替换实现向左轮转数组。
|
||||||
|
|||||||
Reference in New Issue
Block a user