刷leetcode中常用的go基础语法点


基础声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 局部变量
x := 0
s := []int{1, 2, 3}
m := map[int]string{1: "a"}

// 空 slice / map(之后用 append 填)
s := make([]int, 0) // nil slice 也能 append,但 make 意图更明确
s := make([]int, 0, 10) // 预分配容量,知道大概长度时更高效
m := make(map[int]string)

// 二维 slice
dp := make([][]int, n)
for i := range dp {
dp[i] = make([]int, m)
}

Slice 操作(每日必用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 追加
s = append(s, x)

// 末尾删除(模拟 pop)
s = s[:len(s)-1]

// 头部删除(模拟队列 pop)
s = s[1:]

// 子切片 [left, right)
sub := s[left:right]

// 遍历
for i, v := range s { } // 下标 + 值
for i := range s { } // 只要下标
for _, v := range s { } // 只要值

// 拷贝
copy(dst, src)

// 反转(没有内置函数)
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}

Map 操作

1
2
3
4
5
6
7
8
9
m := make(map[int]int)

m[key] = value // 写
v := m[key] // 读(不存在返回零值,不会 panic)
v, ok := m[key] // 安全读,ok 判断是否存在
delete(m, key) // 删除(key 不存在也没事,不报错)

// 遍历(顺序随机)
for k, v := range m { }

循环

1
2
3
4
5
6
7
8
9
10
11
12
// 标准三段式
for i := 0; i < n; i++ { }

// while 形式
for condition { }
for left < right { }

// 死循环
for { }

// 倒序遍历
for i := n - 1; i >= 0; i-- { }

排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import "sort"

// int / string 升序
sort.Ints(nums)
sort.Strings(strs)

// 自定义排序
sort.Slice(nums, func(i, j int) bool {
return nums[i] > nums[j] // 降序
})

// 结构体排序
sort.Slice(users, func(i, j int) bool {
return users[i].Age < users[j].Age
})

栈和队列(用 slice 模拟)

1
2
3
4
5
6
7
8
9
10
11
// 栈
stack := []int{}
stack = append(stack, x) // push
top := stack[len(stack)-1] // peek
stack = stack[:len(stack)-1] // pop

// 队列(效率低但写法简单)
queue := []int{}
queue = append(queue, x) // enqueue
front := queue[0] // peek
queue = queue[1:] // dequeue

堆(优先队列)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import "container/heap"

// 小顶堆
type MinHeap []int

func (h MinHeap) Len() int { return len(h) }
func (h MinHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h MinHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *MinHeap) Push(x any) { *h = append(*h, x.(int)) }
func (h *MinHeap) Pop() any {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}

h := &MinHeap{}
heap.Init(h)
heap.Push(h, x)
top := heap.Pop(h).(int) // 取出最小值

数学 / 极值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import "math"

math.MaxInt32
math.MinInt32
math.MaxFloat64

// int 的 max/min(Go 没有内置,自己写)
func max(a, b int) int {
if a > b { return a }
return b
}
func min(a, b int) int {
if a < b { return a }
return b
}

// abs
func abs(x int) int {
if x < 0 { return -x }
return x
}

字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// rune 遍历(正确处理中文)
for _, ch := range s {
// ch 是 rune 类型
}

// 取第 i 个字符(仅限 ASCII,中文会错)
s[i] // 返回 byte

// 修改字符串:先转 []rune 或 []byte
b := []byte(s)
b[i] = 'x'
s = string(b)

// 拼接
s := strings.Join(list, "")

// 分割
parts := strings.Split(s, " ")

// strings.Builder(拼接性能敏感时)
var sb strings.Builder
sb.WriteString("hello")
sb.WriteByte('!')
result := sb.String()

BFS / DFS 常用模板

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
// BFS 最短路径
queue := [][]int{{startX, startY}}
visited := make([][]bool, rows)
for queue != nil {
size := len(queue)
for k := 0; k < size; k++ {
cur := queue[0]
queue = queue[1:]
for _, dir := range [][]int{{0,1},{0,-1},{1,0},{-1,0}} {
nx, ny := cur[0]+dir[0], cur[1]+dir[1]
if nx >= 0 && nx < rows && ny >= 0 && ny < cols && !visited[nx][ny] {
visited[nx][ny] = true
queue = append(queue, []int{nx, ny})
}
}
}
steps++
}

// DFS 递归
func dfs(grid [][]int, i, j int, visited [][]bool) {
if i < 0 || i >= len(grid) || j < 0 || j >= len(grid[0]) || visited[i][j] {
return
}
visited[i][j] = true
dfs(grid, i+1, j, visited)
dfs(grid, i-1, j, visited)
dfs(grid, i, j+1, visited)
dfs(grid, i, j-1, visited)
}

LeetCode 常量(复制到文件最上面)

1
2
const MOD = 1_000_000_007
const INF = math.MaxInt32

MOD 在动态规划计数题里几乎每次都有。


常用类型转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// int ↔ string
strconv.Itoa(x) // int → string
strconv.Atoi(s) // string → int(返回 (int, error))

// string ↔ byte
[]byte("hello") // string → []byte
string(bs) // []byte → string

// rune ↔ string
string(r) // rune → string
[]rune(s) // string → []rune

// int → float64
float64(x)

// float64 → int
int(f)

写在同一个文件顶部的 import 块

1
2
3
4
5
6
import (
"math"
"sort"
"strconv"
"strings"
)

LeetCode 编辑器里不需要写 import——它会自动补。但写到本地 Go 文件时上面这段直接粘贴到文件头。