子集 - Time/Space 分析
Subsets - Time/Space Analysis
问题是为给定的整数数组生成子集。
例如,
输入: [0, 1, 2]
输出: [ [], [0], [1], [2], [0,1], [0,2], [1, 2], [0, 1, 2]]
我需要帮助分析我解决此问题的时间和 space 复杂性。
时间复杂度
就像我知道子集的总数是 2^N 所以时间复杂度至少是 2 ^N 然后我的树的高度就像 N 的最坏情况一样,但随后我在依赖于 N 的 2 个嵌套循环内执行递归...所以我想知道我的时间复杂度是否会像 O(2^ N * N ^ 3)?好吧,如果是这样的话……我的代码很糟糕。
Space 复杂度
space 将消耗 2^N 行和最多 N 个元素,因此我知道 space 复杂度为 O(2^N * N)。
如果我有什么误解请告诉我!谢谢。
def powerset(array):
# Write your code here.
start_len = 0
answer = [[]]
while(start_len <= len(array)):
i = 0
while(i < len(array)):
print(array[i:])
powersetHelper([], array[i:], start_len, answer)
i += 1
start_len += 1
print(answer)
return answer
def powersetHelper(chosen, choices, target_len, answer):
# Write your code here.
chosen.append(choices[0])
if(len(chosen) == target_len):
if(chosen not in answer):
answer.append(chosen)
else:
i = 1
while(i < len(choices)):
chosen_copy = chosen.copy()
powersetHelper(chosen_copy, choices[i:], target_len, answer)
i += 1
这段代码实际上是Ω(N * 4^N)
(即至少是这个运行时),只是因为这两行
if(chosen not in answer):
answer.append(chosen)
每次添加新子集时,它都会对所有子集执行线性搜索。如果您的输入列表没有重复,并且您已经编写了 powerset 算法来避免重复,那么这些行是不必要的。无论哪种方式,使用 set()
而不是列表进行包含检查,因为这在运行时占主导地位。
Theta(N * 2^N)
的space复杂度是正确的;如果您要存储所有子集,这是最佳选择。不幸的是,如果包含检查问题得到解决,我不知道代码的时间复杂度。看起来在powerset和powersetHelper中执行了大量不必要的工作和递归调用,我很难理解算法的逻辑。根据经验测试(将全局计数器放入函数中),修复包含检查后的操作数增长非常非常接近 n^2 * 2^n 的常数倍数。
问题是为给定的整数数组生成子集。
例如,
输入: [0, 1, 2]
输出: [ [], [0], [1], [2], [0,1], [0,2], [1, 2], [0, 1, 2]]
我需要帮助分析我解决此问题的时间和 space 复杂性。
时间复杂度
就像我知道子集的总数是 2^N 所以时间复杂度至少是 2 ^N 然后我的树的高度就像 N 的最坏情况一样,但随后我在依赖于 N 的 2 个嵌套循环内执行递归...所以我想知道我的时间复杂度是否会像 O(2^ N * N ^ 3)?好吧,如果是这样的话……我的代码很糟糕。
Space 复杂度
space 将消耗 2^N 行和最多 N 个元素,因此我知道 space 复杂度为 O(2^N * N)。
如果我有什么误解请告诉我!谢谢。
def powerset(array):
# Write your code here.
start_len = 0
answer = [[]]
while(start_len <= len(array)):
i = 0
while(i < len(array)):
print(array[i:])
powersetHelper([], array[i:], start_len, answer)
i += 1
start_len += 1
print(answer)
return answer
def powersetHelper(chosen, choices, target_len, answer):
# Write your code here.
chosen.append(choices[0])
if(len(chosen) == target_len):
if(chosen not in answer):
answer.append(chosen)
else:
i = 1
while(i < len(choices)):
chosen_copy = chosen.copy()
powersetHelper(chosen_copy, choices[i:], target_len, answer)
i += 1
这段代码实际上是Ω(N * 4^N)
(即至少是这个运行时),只是因为这两行
if(chosen not in answer):
answer.append(chosen)
每次添加新子集时,它都会对所有子集执行线性搜索。如果您的输入列表没有重复,并且您已经编写了 powerset 算法来避免重复,那么这些行是不必要的。无论哪种方式,使用 set()
而不是列表进行包含检查,因为这在运行时占主导地位。
Theta(N * 2^N)
的space复杂度是正确的;如果您要存储所有子集,这是最佳选择。不幸的是,如果包含检查问题得到解决,我不知道代码的时间复杂度。看起来在powerset和powersetHelper中执行了大量不必要的工作和递归调用,我很难理解算法的逻辑。根据经验测试(将全局计数器放入函数中),修复包含检查后的操作数增长非常非常接近 n^2 * 2^n 的常数倍数。