1. 基础算法入门:为什么每个程序员都需要掌握
算法就像厨师的刀工,是程序员的基本功。我见过太多开发者一上来就想学框架、做项目,结果遇到稍微复杂点的问题就束手无策。Day03这个阶段正是打基础的关键时刻,那些看似简单的排序、查找算法,其实蕴含着计算机科学最精妙的思想。
十年前我刚入行时,觉得算法只是面试时才需要的东西。直到有次处理百万级数据时,一个糟糕的循环让程序跑了整整一晚上,而同事用二分查找十分钟就搞定了——那次教训让我明白,算法不是考试题,而是实打实的生产力工具。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 必须掌握的五大基础算法
2.1 排序算法:从冒泡到快排
先说说最经典的冒泡排序。虽然它的时间复杂度是O(n²),但在小数据量(比如n<50)时反而比快排更快,因为它的常数因子极小。我常用这个例子给新人演示:
python复制def bubble_sort(arr):
n = len(arr)
for i in range(n-1):
for j in range(n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
关键点:外层循环控制轮数,内层循环比较相邻元素。注意第二层循环的边界是n-i-1,这是已经排序部分的优化。
快排则是另一个极端,平均O(nlogn)但最坏O(n²)。我在实际项目中会做三点优化:
- 三数取中法选择pivot
- 对小数组切换成插入排序
- 使用尾递归优化
2.2 查找算法:二分查找的七个细节
二分查找看似简单,但据我统计面试中能完全写对的人不到30%。最常见的错误包括:
- 循环条件写成left <= right还是left < right?
- mid计算用(left+right)/2可能溢出
- 如何确定左右边界更新方式?
这是我打磨多年的模板:
python复制def binary_search(nums, target):
left, right = 0, len(nums)-1
while left <= right:
mid = left + (right-left)//2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
2.3 递归与分治:理解递归三要素
递归代码写起来优雅,但调试起来要命。我总结的递归三要素:
- 终止条件(必须放在最前面!)
- 当前层处理逻辑
- 下探到下一层
比如计算斐波那契数列:
python复制def fib(n):
if n <= 1: # 终止条件
return n
return fib(n-1) + fib(n-2) # 分解问题
警告:这种写法存在大量重复计算,实际要用备忘录优化。我在生产环境见过因为这个导致服务崩溃的案例。
2.4 贪心算法:局部最优的陷阱
贪心算法就像下棋时的局部最优解,有时候管用(比如零钱兑换问题),有时候会掉坑里。判断能否用贪心的关键:
- 问题具有最优子结构
- 无后效性
- 能证明局部最优导致全局最优
举个反例:背包问题如果用贪心按价值密度排序,可能得不到最优解。
2.5 动态规划:从斐波那契到背包问题
DP是算法中的重头戏。我教新人时总会先让他们写递归版,再改记忆化搜索,最后转DP表格。以爬楼梯问题为例:
- 递归版(指数级复杂度)
- 记忆化搜索(加个cache字典)
- DP表格(O(n)空间)
- 状态压缩(O(1)空间)
python复制def climb_stairs(n):
if n <= 2: return n
dp = [0]*(n+1)
dp[1], dp[2] = 1, 2
for i in range(3, n+1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
3. 算法实战中的六个经验技巧
3.1 如何选择合适的数据结构
有次我优化一个实时排行榜,原方案用数组存储+排序,QPS只能到200。后来改用:
- 跳表(查询O(logn))
- 结合哈希表快速定位
性能直接提升到5000QPS。选择数据结构时要考虑: - 数据规模
- 操作频率(增删改查比例)
- 内存限制
3.2 边界条件处理的艺术
算法题80%的bug出在边界条件。我的检查清单:
- 空输入
- 单元素/双元素
- 极值(如INT_MAX)
- 重复元素
- 有序/逆序输入
3.3 时间复杂度的实战估算
面试常问"这个算法能处理多大数量级?"我的经验公式:
- 1秒内:
- O(n!):n≤10
- O(2ⁿ):n≤20
- O(n³):n≤500
- O(n²):n≤10⁴
- O(nlogn):n≤10⁶
- O(n):n≤10⁷
3.4 空间复杂度的隐藏成本
递归调用栈深度、临时数组分配都可能成为瓶颈。有次我用递归处理深度嵌套的JSON,直接爆栈。解决方案:
- 改为迭代
- 限制递归深度
- 使用尾递归优化(部分语言支持)
3.5 测试用例的设计方法
我习惯用"3+2+1"法则设计测试用例:
- 3个常规案例(包括题目给的示例)
- 2个边界案例(空输入、极值等)
- 1个破坏性案例(故意乱序、重复等)
3.6 调试算法的可视化技巧
复杂算法我推荐用可视化工具:
- 打印中间状态(如排序过程中的数组)
- 画递归树(理解递归调用过程)
- 使用Python Tutor等在线可视化工具
4. 常见算法面试题精讲
4.1 两数之和的七种解法
这道题可以从暴力法O(n²)一直优化到哈希表O(n):
python复制def twoSum(nums, target):
seen = {}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
注意:这要求数组元素唯一。如果有重复,需要额外处理。
4.2 链表反转的迭代与递归
迭代法需要维护三个指针:
python复制def reverseList(head):
prev = None
curr = head
while curr:
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node
return prev
递归法则更考验对调用栈的理解:
python复制def reverseList(head):
if not head or not head.next:
return head
new_head = reverseList(head.next)
head.next.next = head
head.next = None
return new_head
4.3 二叉树遍历的Morris算法
传统递归遍历需要O(n)空间,Morris遍历能做到O(1)空间:
python复制def morris_inorder(root):
curr = root
while curr:
if not curr.left:
print(curr.val)
curr = curr.right
else:
# 找前驱节点
pre = curr.left
while pre.right and pre.right != curr:
pre = pre.right
if not pre.right:
pre.right = curr
curr = curr.left
else:
pre.right = None
print(curr.val)
curr = curr.right
4.4 拓扑排序的两种实现
Kahn算法(基于入度):
python复制def topological_sort(vertices, edges):
in_degree = {v:0 for v in vertices}
graph = {v:[] for v in vertices}
for u, v in edges:
graph[u].append(v)
in_degree[v] += 1
queue = [v for v in vertices if in_degree[v] == 0]
result = []
while queue:
u = queue.pop(0)
result.append(u)
for v in graph[u]:
in_degree[v] -= 1
if in_degree[v] == 0:
queue.append(v)
return result if len(result) == len(vertices) else []
DFS版本则需要记录访问状态和逆序输出。
5. 算法学习路线与资源推荐
5.1 分阶段学习计划
根据我带新人的经验,建议这样安排:
- 第1周:复杂度分析+基础排序/查找
- 第2周:递归/分治+基础数据结构
- 第3周:贪心+二分
- 第4周:DFS/BFS+回溯
- 第5周:DP+高级数据结构
5.2 经典教材与在线资源
纸质书:
- 《算法导论》(理论扎实)
- 《算法4》(Java实现)
- 《剑指Offer》(面试向)
在线:
- LeetCode(按标签刷题)
- VisuAlgo(可视化学习)
- TopCoder教程(竞赛向)
5.3 刷题的正确姿势
我总结的"三刷法":
- 第一遍:按类型集中刷(如两周专攻DP)
- 第二遍:按难度随机刷
- 第三遍:模拟面试环境白板编程
5.4 算法在真实项目中的应用
几个典型场景:
- 推荐系统:图算法+排序
- 搜索引擎:字符串匹配+索引
- 金融风控:概率算法+决策树
- 游戏AI:寻路算法+状态机
5.5 持续提升的建议
- 每周至少做3道新题+复习2道旧题
- 参加周赛锻炼临场发挥
- 定期review经典算法实现
- 尝试用不同语言实现同一算法
