Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python &引用;“三笔钱”;问题空间复杂性-为什么是O(n)?_Python_Algorithm_Complexity Theory_Space Complexity - Fatal编程技术网

Python &引用;“三笔钱”;问题空间复杂性-为什么是O(n)?

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

Leetcode-三和

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]