You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

排列算法分析:递归排列算法的时间复杂度是否为O(n!)?

递归排列算法疑问解答:代码逻辑 + 时间复杂度分析

嘿,先别被递归搞疯!咱们一步步拆解你代码里的疑问,再聊聊时间复杂度的问题~

先解释你代码里的两个疑问

首先把你的代码格式化一下,方便咱们看:

def permute(s):
    out = []
    if len(s) == 1:
        # wouldn't setting out replace everything in out?
        out = [s]
    else:
        for i, let in enumerate(s):
            # how does it know that I only want 2 strings?
            for perm in permute(s[:i] + s[i+1:]):
                out += [let + perm]
    return out

print(permute("cat"))

疑问1:# wouldn't setting out replace everything in out?

完全不用担心“替换掉之前的out”!这里的out是函数的局部变量,每次递归调用permute都会在新的函数栈帧里创建一个全新的out,和上层递归的out完全没关系。

当len(s) == 1时,这是递归的基准情况——单个字符的排列只能是它自己,所以把out设为[s]是完全合理的。这个值会返回给上层递归,上层会用它来拼接更长的排列。

疑问2:# how does it know that I only want 2 strings?

它根本不知道你“只想要2个字符串”,这是递归的自然结果呀!

举个例子,当处理"cat"时:

  • 第一次循环取字符'c',剩下的子串是"at",调用permute("at")会返回["at", "ta"],所以拼接后得到["cat", "cta"];
  • 第二次循环取字符'a',剩下的子串是"ct",调用permute("ct")返回["ct", "tc"],拼接得到["act", "atc"];
  • 第三次循环取字符't',剩下的子串是"ca",调用permute("ca")返回["ca", "ac"],拼接得到["tca", "tac"]。

所有结果合并起来就是6个排列(3!),而递归到长度为2的字符串时,自然会生成2个排列(2!)——这是算法遍历所有可能组合的必然结果,不是刻意限定的。

时间复杂度:O(n!)是正确的吗?

答案是完全正确,咱们来理清楚原因:

  1. 排列总数的下限:n个不同字符的排列总数是n!,算法必须生成每一个排列,这部分的工作量至少是O(n!),因为每个排列都要被构造和存储。
  2. 递归过程的总工作量:对于长度为k的字符串,递归会触发k次对长度为k-1的字符串的调用。把所有递归步骤的工作量加起来:
    n! + (n-1)*(n-1)! + (n-2)*(n-2)! + ... + 1*1! = (n+1)! - 1
    
    而(n+1)!和n!是同阶的(大O表示法忽略常数倍数),所以总时间复杂度就是O(n!)。
  3. 最优性:因为必须生成所有n!个排列,所以这个算法的时间复杂度已经是最优的了——不可能有比O(n!)更快的算法来生成所有排列。

内容的提问来源于stack exchange,提问作者edmamerto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:05:55