30天Go学习 - 算法题库与解答
总计 ~45 道,按难度和主题分类,全用Go实现
Week 1 算法清单(12道)
Day 1: 数组/哈希(3道)
1. Two Sum - Easy
给定数组和target,找两个数相加等于target
Input: [2,7,11,15], target=9
Output: [0,1]
关键点: Map一遍扫过,O(n)时间
Go实现框架:
func twoSum(nums []int, target int) []int {
// 用map存 value -> index
// 遍历时检查 target-num 是否在map里
}
2. Valid Anagram - Easy
给两个字符串,判断是否是anagram
Input: s="anagram", t="nagaram"
Output: true
关键点: 频率统计,两个map相等或排序后相等
3. Group Anagrams - Medium
给字符串数组,分组anagrams
Input: ["eat","tea","ate","eat","tan","ate"]
Output: [["eat","tea","ate","eat"],["tan"]]
关键点: 用排序后的string作key,分组
Day 2: 滑动窗口(3道)
4. Longest Substring Without Repeating Characters - Medium
找最长子串,无重复字符
Input: "abcabcbb"
Output: 3 ("abc")
关键点: 双指针 + map记录字符位置
5. Valid Parentheses - Easy
判断括号序列是否合法
Input: "()"
Output: true
Input: "([)]"
Output: false
关键点: 用stack,处理三种括号
6. Binary Search - Easy
在排序数组里查找target
Input: [-1,0,3,5,9,12], target=9
Output: 4
关键点: 经典二分,注意边界
Day 3: 链表与区间(3道)
7. Merge Intervals - Medium
合并重叠区间
Input: [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
关键点: 先排序,再合并
8. Search Insert Position - Easy
在排序数组里找target位置,没有就返回插入位置
Input: [1,3,5,6], target=5
Output: 2
关键点: 二分变体
9. Top K Frequent Elements - Medium
找前K个频率最高的元素
Input: [1,1,1,2,2,3], k=2
Output: [1,2]
关键点: Heap或sort,O(nlogn)或O(n)
Day 4: 链表(3道)
10. Reverse Linked List - Easy
反转链表
Input: 1->2->3->4
Output: 4->3->2->1
关键点: 三指针(prev/curr/next),迭代或递归
11. Linked List Cycle - Easy
判断链表是否有环
Input: 3->2->0->-4 (tail指向2)
Output: true
关键点: 快慢指针,Floyd's algorithm
12. Merge Two Sorted Lists - Easy
合并两个排序链表
Input: 1->2->4, 1->3->4
Output: 1->1->2->3->4->4
关键点: 双指针,处理null cases
Week 2 算法清单(12道)
Day 8-9: 树(5道)
13. Maximum Depth of Binary Tree - Easy
14. Balanced Binary Tree - Easy
15. Lowest Common Ancestor of BST - Easy
16. Level Order Traversal (BFS) - Medium
17. Validate BST - Medium
Day 10-12: 图与DP(7道)
18. Number of Islands - Medium
19. Max Area of Island - Medium
20. Subsets - Medium
21. Permutations - Medium
22. Combination Sum - Medium
23. House Robber - Medium
24. Coin Change - Medium
Week 3-4 算法清单(21道)
DP与高级(21道)
25. Unique Paths - Medium
26. Maximum Product Subarray - Medium
27. Longest Repeating Character Replacement - Medium
...
45. LRU Cache - Hard
📋 按主题分类
数组 / 哈希 (10道)
- Two Sum
- Valid Anagram
- Group Anagrams
- Top K Frequent
- Product of Array Except Self
- Maximum Subarray
- 3Sum
- Unique Paths
- ...
字符串(5道)
- Longest Substring Without Repeating
- Valid Parentheses
- Longest Repeating Character Replacement
- Permutation in String
- Minimum Window Substring
链表(5道)
- Reverse Linked List
- Linked List Cycle
- Merge Two Sorted Lists
- Merge K Sorted Lists
- ...
树 / 图(8道)
- Maximum Depth
- Balanced Binary Tree
- LCA
- Number of Islands
- Clone Graph
- ...
DP(8道)
- House Robber
- Coin Change
- Unique Paths
- Max Product Subarray
- Word Break
- ...
其他(9道)
- LRU Cache
- Binary Search
- Merge Intervals
- ...
📊 难度分布
| 难度 |
数量 |
例子 |
| Easy |
18道 |
Two Sum、Valid Parentheses、Reverse Linked List |
| Medium |
22道 |
Top K Frequent、Merge Intervals、House Robber |
| Hard |
5道 |
LRU Cache、Binary Tree Max Path Sum、Trapping Rain Water |
🔧 Go实现关键点
必会的Go数据结构
1. Map(哈希表)
m := make(map[int]int)
m[key] = value
if v, ok := m[key]; ok { /* 检查存在 */ }
delete(m, key)
2. Slice(动态数组)
s := []int{1, 2, 3}
s = append(s, 4)
for i, v := range s { /* 遍历 */ }
3. 堆(container/heap)
import "container/heap"
h := &IntHeap{}
heap.Push(h, 1)
v := heap.Pop(h)
4. 双向链表(container/list)
import "container/list"
l := list.New()
l.PushBack(1)
for e := l.Front(); e != nil; e = e.Next() { }
5. 栈 / 队列(用Slice)
// Stack
stack := []int{}
stack = append(stack, x) // Push
x := stack[len(stack)-1] // Top
stack = stack[:len(stack)-1] // Pop
// Queue
queue := []int{}
queue = append(queue, x) // Enqueue
x := queue[0] // Front
queue = queue[1:] // Dequeue
📖 学习路线
Week 1(12道)- 基础扎实
目标: 这些题手到擒来,复杂度分析清楚
Week 2(12道)- 深化算法
目标: 能解释为什么用这个算法,而不是那个
Week 3-4(21道)- 冲刺
- 动态规划(关键)
- 高级数据结构(LRU、Trie)
目标: 在Agent系统的context里能用上(如Day 12的eval,Day 25的caching)
✅ 刷题建议
每天时间分配(3小时中)
- 早上 30 分钟:学一道新题的思路(不看代码)
- 上午 1 小时:自己写Go代码实现
- 下午 30 分钟:对标答案,理解最优方案
- 晚上 1 小时:相关题目的扩展变体
每周检查清单
面试前冲刺
- 刷过的题目:再过一遍思路,不用全写
- 未刷过的题目:看到就能识别类型和解法
- 关键: 能讲清楚Why,不只是How
🔗 题目与Agent系统的关联
| 算法 |
用处 |
| Two Sum / Hash |
Day 3 Tool去重 |
| Sliding Window |
Day 9 Token窗口管理 |
| Binary Search |
Day 12 Rerank优化 |
| DFS/BFS |
Day 2 RAG检索路径 |
| Heap |
Day 11 Priority queue工具调度 |
| DP |
Day 25 Cost优化、缓存策略 |
| LRU |
Day 25 缓存实现 |
| Trie |
日期之后的扩展(autocomplete) |
📝 Go刷题常见误区
❌ 坑1:Slice操作
// 坏:会panic
s := []int{1, 2, 3}
s = s[3:] // 索引越界
s[0] = 1 // 空slice写入
// 好:先检查
if len(s) > 0 {
x := s[0]
}
❌ 坑2:Map的零值
// 坏:无法区分"不存在"和"值为0"
m := make(map[int]int)
if m[999] == 0 { /* 可能不存在,也可能值就是0 */ }
// 好:用comma-ok
if v, ok := m[999]; ok { /* 确实存在 */ }
❌ 坑3:指针和nil
// 坏:指针没初始化
var p *int
*p = 10 // panic: nil pointer
// 好:初始化或检查
p := new(int)
*p = 10 // OK
❌ 坑4:递归返回值
// 坏:忘了处理nil
func maxDepth(root *TreeNode) int {
if root == nil { return 0 }
left := maxDepth(root.Left) // 可能0也可能>0
// 没用left的值,错了
}
// 好:明确使用
left := maxDepth(root.Left)
right := maxDepth(root.Right)
return 1 + max(left, right)
🎯 最后目标
Day 30时,你应该能:
- 45道题闭眼写
- 遇到新题能在5分钟内识别类型
- 能讲清楚为什么用这个算法
- 复杂度分析深到没人能挑战
这样面试官问"你有什么擅长的吗",你可以说:
LeetCode上我刷过45道题,覆盖数组、链表、树、图、DP等主题。我在Agent系统的Day 25还用到了LRU缓存优化成本和延迟。算法对我来说不是刷题,而是系统设计的工具。
简直完美。👌
📚 推荐资源
- LeetCode(题库)
- 《剑指Offer》(中文)
- NeetCode 150(精选)
- Go官方文档container包
Ready to start? 💪