很多人学算法,卡住的不是代码。

而是这些词:

  • 动态规划
  • 贪心
  • 分治

听起来像三门不同学科。

但今天我们用一个统一视角讲清楚:

算法,本质就是在降低不确定性(熵)。

而代码,就是你执行“降熵策略”的工具。


第一部分:从暴力开始(必须写出来)

🎯 问题:找数组中的某个数

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:优化降熵速度

目标只有一个:

更快地减少不确定性


最后送你三句话:


暴力,是最慢的降熵。
优化,是更聪明的降熵。
算法,是设计降熵路径的艺术。