很多人学算法,卡住的不是代码。
而是这些词:
- 动态规划
- 贪心
- 分治
听起来像三门不同学科。
但今天我们用一个统一视角讲清楚:
算法,本质就是在降低不确定性(熵)。
而代码,就是你执行“降熵策略”的工具。
第一部分:从暴力开始(必须写出来)
🎯 问题:找数组中的某个数
def find_target(nums, target):
for i in range(len(nums)):
if nums[i] == target:
return i
return -1
🧠 发生了什么?
- 你不知道答案在哪(高熵)
- 你一个一个试(逐步降熵)
💡 本质
暴力 = 最原始的降熵方式
优点:
- 一定正确
缺点:
- 太慢
第二部分:第一种降熵加速——“砍掉一半”(二分查找)
🎯 条件:数组有序
def binary_search(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
🧠 核心变化
暴力:
一个一个试
二分:
每次砍掉一半
💡 熵视角解释
有序 = 信息
信息 = 可以直接消灭一半不确定性
🔥 结论
二分查找 = 利用“有序性”进行指数级降熵
第三部分:第二种降熵——避免重复(动态规划)
🎯 问题:斐波那契数列
❌ 暴力写法(千万别跳过)
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)
🧠 问题在哪?
画一下调用过程:
fib(5)
= fib(4) + fib(3)
= fib(3) + fib(2) + fib(3)
👉 fib(3) 被算了很多次!
💡 本质问题
重复降熵(重复计算同一个问题)
✅ 优化:记忆化
memo = {}
def fib(n):
if n in memo:
return memo[n]
if n <= 1:
return n
memo[n] = fib(n-1) + fib(n-2)
return memo[n]
🧠 发生了什么?
算过 → 记住 → 直接用
💡 熵解释
动态规划 = 不再重复处理已经降低过的熵
🚀 再优化:去掉递归
def fib(n):
if n <= 1:
return n
a, b = 0, 1
for _ in range(2, n+1):
a, b = b, a + b
return b
🔥 本质升级
只保留“必要信息”,继续压缩熵
第四部分:第三种降熵——剪掉无效分支(回溯剪枝)
🎯 问题:从数组中找所有和为 target 的组合
❌ 暴力回溯
def backtrack(nums, path, start, target):
if sum(path) == target:
print(path)
return
if start == len(nums):
return
for i in range(start, len(nums)):
backtrack(nums, path + [nums[i]], i + 1, target)
🧠 问题
👉 会走很多“明显不可能成功”的路径
✅ 加剪枝
def backtrack(nums, path, start, target):
if target == 0:
print(path)
return
if target < 0:
return # 剪掉
for i in range(start, len(nums)):
backtrack(nums, path + [nums[i]], i + 1, target - nums[i])
💡 本质
剪枝 = 提前终止不可能成功的降熵路径
第五部分:第四种降熵——拆问题(分治)
🎯 问题:排序
思路(归并排序)
def merge_sort(nums):
if len(nums) <= 1:
return nums
mid = len(nums) // 2
left = merge_sort(nums[:mid])
right = merge_sort(nums[mid:])
return merge(left, right)
def merge(left, right):
result = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result.extend(left[i:])
result.extend(right[j:])
return result
💡 本质
分治 = 把大熵问题,拆成小熵问题
第六部分:统一总结(最关键)
现在你可以这样理解所有算法:
| 方法 | 本质降熵方式 |
|---|---|
| 暴力 | 一点点试 |
| 二分 | 每次砍一半 |
| 动态规划 | 避免重复 |
| 剪枝 | 提前停止 |
| 分治 | 降低规模 |
第七部分:做题通用模板(超实用)
以后你拿到一道题,按这个流程走:
🧩 Step 1:先写暴力
先保证:我能做对
🔍 Step 2:找“浪费”
问自己:
- 有没有重复计算?👉 DP
- 有没有明显不可能?👉 剪枝
- 有没有有序性?👉 二分
- 能不能拆?👉 分治
⚡ Step 3:优化降熵速度
目标只有一个:
更快地减少不确定性
最后送你三句话:
暴力,是最慢的降熵。
优化,是更聪明的降熵。
算法,是设计降熵路径的艺术。
参与讨论