此powerset函数的时间和空间复杂度是多少?

时间:2019-05-01 13:31:17

标签: python-3.x recursion time-complexity space-complexity powerset

您好,我一直在练习算法和数据结构,并且解决了https://leetcode.com/problems/subsets/这是powerset函数的问题,但是看来我的解决方案太慢了。 这是代码:

def subsets(array):
    set = [array]
    n = len(array)
    for i in range(n):
        tmp_subsets = subsets(array[:i] + array[i+1:])
        for subset in tmp_subsets:
            if subset not in set:
                set.append(subset)
    return set

我知道还有其他更好/更快的解决方案,但是我试图了解这一解决方案在时间和空间上的复杂性。

我认为这里的时间复杂度为O(n^n),因为递归树每个级别有n个分支,总共n个级别是否正确?

因此,它比最优的O(2^n)解决方案还差。

虽然我不确定空间的复杂性,我的直觉是O(2^n),但是当我绘制递归树时,这有点令人困惑,因为在递归堆栈最大的那一点上,我正在使用的空间是:

space_for_level(0)+space_for_level(1)+...+space_for_level(n)
n + (n-1) +...+ 1 = O(n^2)

但是最后,当我返回所有内容时,set的大小为O(2^n),所以我的空间复杂度将为O(2^n + n^2) = O(2^n)

我的分析在时间和空间上都正确吗?欢迎任何帮助我以更清晰的方式思考的指针。

1 个答案:

答案 0 :(得分:1)

时间复杂度

时间复杂度可以归纳为以下递归关系:

T(n) = n * T(n-1) + n * 2^(n-1)

因为有一个主循环运行n次,并且每次首先生成(n-1)其余元素(T(n-1))的子集,并且然后遍历(2^(n-1)

注意,该关系假定循环中的每个其他操作都需要恒定的时间,这是一个合理的近似值,因为随着n的增长,其影响最小。例如以下操作:

if subset not in set

花费固定时间(列表长度花费线性时间,set.append(subset)通常也不是恒定时间),但现在暂时忽略它(您可以得到图片)以及如何分析代码。

递归关系表明复杂性至少是指数

空间复杂度

首先,生成n的所有子集,这意味着至少复杂度为O(2^n)。但是,由于在每个步骤中子集的递归和重新生成,空间复杂度远不止于此。具体而言,在每个循环步骤中,将生成n-1子集的一个运行副本,然后将其扩充为原始子集。我们有:

S(n) = S(n-1) + 2^n

由于每次对子集的调用都会生成{strong>其余子集(即1)的S(n-1)中间运行副本,加上它将这些元素合并为原始子集,即{ {1}}

注意,我们不计算存储子集的每个项目所需的存储空间,它本身需要存储2^n左右的复杂性,但是认为这是对O(n)为简单起见(例如,将较小的O(1)用二进制编码存储为一个词,例如一个子集),因此子集的整个存储量(不计算辅助存储量)将简单地为{{1} }复杂度(另外,如注释中所述,仅存储n <= 64的所有子集的存储复杂度为O(2^n)

递归关系表明复杂性至少是指数

解决方案

由于master theorem无法应用于这些递归关系(如前所述),请检查methods for solving first-order recurrence relations with variable coefficients以解决上述关系(空间复杂度就像算术级数,而时间复杂度具有更复杂的形式)并获得确切形式的复杂度(尽管解决方案可能非常复杂,并且仍然会以一种或另一种方式呈指数形式)

更好的复杂性

可以通过利用子集的结构和属性来实现更好的时间和空间复杂性(给定顺序,例如 lexicographic )。

特别是,已经生成的子集与其前任和后继者之间有着密切的关系。因此,可以对继承者(序列中的下一个子集)进行生成,而对其继承者所做的改动很小(例如,仅添加或删除单个元素)。

例如,代码生成许多重复项,然后对其进行测试,以检查它们是否已经存在,可以完全避免这种情况。再加上不需要递归,因此可以消除递归的时间和空间复杂性。此外,在主循环内只需要恒定的存储空间(假设可以仅对前一个子集进行最少且恒定的更改即可生成下一个子集),依此类推。所有这些优化都以一种或多种方式利用子集在确定顺序下的对称性和性质。

PS。您还可以在computer.science.stackexchange上研究与算法复杂度有关的类似问题