Python &引用;“三笔钱”;问题空间复杂性-为什么是O(n)?
Leetcode-三和Python &引用;“三笔钱”;问题空间复杂性-为什么是O(n)?,python,algorithm,complexity-theory,space-complexity,Python,Algorithm,Complexity Theory,Space Complexity,Leetcode-三和 def threeNumberSum(数组,targetSum): 数组=已排序(数组) 结果=[] 对于idx,枚举中的元素(数组): i=idx+1 j=透镜(阵列)-1 目标=目标总和-要素 而i
def threeNumberSum(数组,targetSum):
数组=已排序(数组)
结果=[]
对于idx,枚举中的元素(数组):
i=idx+1
j=透镜(阵列)-1
目标=目标总和-要素
而i
所以时间是O(n^2),我对此没意见,但根据Algoexpert.io,空间是O(n),我不知道为什么。他的解释是:
我们可能最终会存储数组中的每一个数字,如果每个数字都用在某个三元组中,我们将存储大量数字,这些数字将被O(n)空间限制。即使某些数字被多次使用,也将被O(n)空间限制
但是我还不能理解他的解释。如果所提供的数组具有(几乎)所有唯一的三重排列并与该目标数相加,那么空间复杂度不是将为n而是选择3吗?如果它的n选择k=3,简化它就会得到O(n^3)
但是,请注意,对于输入数组,Algoexpert问题还有一个额外的假设,即每个元素都是不同的,而Leetcode版本没有这个假设。我如何在空间复杂度分析中正式处理该信息?如果您的代码是正确的(并且我没有理由假设它是错误的),那么匹配三元组列表的空间复杂度实际上是O(n2)
它不是O(n3),因为任何三元组的第三个成员都是由前两个唯一确定的,所以这个值没有选择的自由
如果所有数字都是唯一的,那么空间要求肯定是O(n2):
您应该能够确信本系列中的术语对应于ceil(n2/2)。(见附件)
如果列表中有重复的数字,则由于在返回的数组中需要唯一的三元组,因此总体空间需求应该减少(相对于n)。您是对的,问题本身就是O(n^3),例如,每个元素都等于
0
,目标也等于0
。谢谢Quang,我在问题中添加了额外的信息,专家问题有一个假设,即每个元素都是不同的。这将如何将空间复杂度缩小到O(n)?n选择3从何而来?在每个内部迭代中最多追加一次,因此不需要额外的计算,空间界限至少是有时间界限的。实际上,这种差异是一种暗示。事实上,对于[1,1,1,1,1…],我们没有选择3。此算法在三元组较少的情况下失败。少于n选择3个三元组,因为它应该是正确的。我认为它确实假设了唯一的元素。啊,那么Algoexpert是错误的,通过@kabanus的解决方案和善意的评论,我终于明白了为什么空间复杂性必须是O(n^2),并且“任何三元组的第三个成员都是由前两个唯一决定的”非常好,这是有意义的,谢谢!从你的链接中,我可以看到这些数字等于天花板函数,这真是太棒了,有数学证明吗?我很想知道如何从数学上分析“三和”空间的复杂性。不幸的是,我不太擅长严格的证明!我希望有人能在math.stackexchange.com上找到一个
def threeNumberSum(array, targetSum):
array = sorted(array)
results = []
for idx, elem in enumerate(array):
i = idx + 1
j = len(array) - 1
target = targetSum - elem
while i < j:
currentSum = array[i] + array[j]
if currentSum == target:
result = [array[i], array[j], array[idx]]
results.append(sorted(result))
i += 1
j -= 1
elif currentSum < target:
i += 1
else:
j -= 1
return results
>>> [len(threeNumberSum(range(-i,i+1),0)) for i in range(1,10)]
[1, 2, 5, 8, 13, 18, 25, 32, 41]