3 ^的变体,n ^ 2 * log(n)时间内有4个数字?

时间:2017-11-02 14:36:09

标签: java arrays algorithm big-o

我正在研究一个我正在进行的算法课程的项目,而且我完全处于冲动状态。赋值是在一个数组中找到所有4个数字的集合,其中i + j = k + l在O(n ^ 2 * log(n))时间内。

我知道这类似于3sum问题,你必须在数组中找到i + j + k = 0的所有集合。我们在演讲中讨论了这个问题的解决方案,通过迭代所有唯一的2对(n ^ 2次)并在排序的数组上使用二进制搜索,在O(n ^ 2 * log(n))时间内解决了这个问题。找到一个满足问题的值(log(n)time)。

但是,我没有看到4号码的问题在这个时候是如何解决的。我认为这是一个安全的猜测,复杂性中的log(n)来自二进制搜索,我将用于最后一个。但是,这意味着我必须在n ^ 2时间内迭代所有可能的3个组合,我认为这是不可能的。

我不是在寻找有人为我做我的工作,但也许如果有人知道如何解决这个问题,他们可以给我一个正确的方向。感谢。

编辑:注意我需要使用排序来解决这个问题也可能会有所帮助。一旦我这样做,我必须编写另一个实现,使用散列更快,但我想我能够做到这一点我自己。我只需要弄清楚如何通过排序来解决问题。

1 个答案:

答案 0 :(得分:1)

保留一个总和和对的排序列表。例如,给定列表

[1, 2, 4, 8, 16, 32, 9, 82]

我们想要识别1+9 = 2+8

识别列表中最大的两个数字,O **(N)**。在这种情况下,他们是(82,32),总和为114.分配114个位置的数组pair_sum;将所有位置设置为空指针。

现在遍历i,j对的列表。对于每对,将两个数字作为索引i + j处的元组值插入。当您在某个索引处发生碰撞时,您已完成:您找到了第二个配对。

我将在一些非常伪的代码中概述这一点;你可以翻译成你最喜欢的实现语言。

银行= [1,2,4,8,16,32,9,82] size = length(bank)

// Find the two largest numbers and allocate the array ...
pair_sum = array[114], initialize to all nulls

for lo in 0:size-1
    for hi in lo+1:size
        sum = bank[lo] + bank[hi]
        if pair_sum[sum]
            // There is already a pair with that sum
            print pair_sum[sum], "and", bank[lo], bank[hi]
        else
            // Record new sum pair
            pair_sum[sum] = tuple(bank[lo], bank[hi])

这是 O(N ^ 2),有界空间取决于数组值。

如果由于实际原因,您不允许将和用作索引,我认为您可以将其改编为二进制搜索和插入,为您提供日志( n)组件。