网络宝典
第二套高阶模板 · 更大气的阅读体验

算法复杂度中的阶乘:为什么它让程序慢得像蜗牛

发布时间:2026-01-02 17:41:47 阅读:238 次

你有没有遇到过这样的情况:写了个小程序,测试几个数字跑得挺快,结果一换成稍微大点的输入,电脑就跟卡住一样,半天出不来结果?可能问题就出在算法的复杂度上,特别是那种涉及“阶乘”的情况。

什么是算法复杂度

简单说,算法复杂度是衡量一个程序“花多少时间”或“占多少内存”的指标。我们最常关注的是时间复杂度,用大O符号表示,比如 O(n)、O(n²),而其中最吓人的之一就是 O(n!),也就是阶乘级复杂度。

阶乘增长有多恐怖

先回忆下阶乘是什么:n! = n × (n-1) × ... × 2 × 1。看起来 harmless,但它的增长速度简直离谱。

举个例子:当你输入是5,5! = 120;输入变成10,10! = 3,628,800;到了15,直接飙升到超过1.3万亿!这意味着,如果每个计算要花1微秒,处理15个元素就得花十几天。

哪里会碰到阶乘复杂度

最常见的场景就是“全排列”问题。比如你要写个程序,找出所有可能的出行顺序:今天要去超市、邮局、银行、健身房四个地方,怎么走路线最短?

这时候程序得尝试所有排列组合:4! = 24种。看着不多,但如果地点增加到10个,就是362万种可能。这就是典型的 O(n!) 算法,暴力穷举每一种顺序。

def permute(nums):
    if len(nums) <= 1:
        return [nums]
    result = []
    for i in range(len(nums)):
        rest = nums[:i] + nums[i+1:]
        for p in permute(rest):
            result.append([nums[i]] + p)
    return result

上面这个 Python 函数会生成列表的所有排列,每次递归都在拆解问题,但代价是调用次数呈阶乘增长。

现实中的应对办法

没人能等几天就为算一条最优路线。所以实际开发中,一旦发现问题是 O(n!),第一反应不是硬刚,而是换思路。

比如旅行商问题(TSP),不用穷举,改用近似算法:贪心法、遗传算法、或者动态规划优化到 O(n²×2ⁿ),虽然还是慢,但至少10个城市也能在秒级出结果。

另一个办法是加剪枝——在搜索过程中提前砍掉明显不行的路径,像下象棋的程序不会真把所有走法都试一遍,而是评估局势及时止损。

理解 O(n!) 的可怕,不是为了背公式,而是学会在写代码前先动脑:这个逻辑会不会随着输入爆炸式增长?一个小优化,可能省下几小时等待。