简体   繁体   English

3sum在n ^ 2 * log(n)时间中有4个数字的变体?

[英]Variant of 3sum with 4 numbers in n^2*log(n) time?

I am working on a project for an algorithms course I'm in and I'm completely at an impass. 我正在为我所从事的算法课程设计一个项目,而我完全陷入了僵局。 The assignment is to find all sets of 4 numbers in an array for which i+j=k+l in O(n^2*log(n)) time. 分配是在一个数组中找到所有4个数字的集合,其中i + j = k + 1的时间为O(n ^ 2 * log(n))。

I know this is similar to the 3sum problem, where you have to find all the sets in an array for which i+j+k=0. 我知道这与3sum问题类似,在该问题中,必须找到i + j + k = 0的数组中的所有集合。 We have discussed a solution to this problem in our lecture that solves it in O(n^2*log(n)) time by iterating through all unique pairs of 2 (n^2 time) and using a binary search on a sorted array to find a value that satisfies the problem (log(n) time). 我们在演讲中讨论了此问题的解决方案,该方法通过迭代所有2对唯一的对(n ^ 2次)并在有序数组上使用二进制搜索,以O(n ^ 2 * log(n))的时间解决该问题。查找满足该问题的值(log(n)时间)。

However, I don't see how the problem with 4 numbers could be solved in this time. 但是,我不知道这次如何解决4个数字的问题。 I think it's a safe guess that the log(n) in the complexity comes from a binary search, which i'll use for the last one. 我认为可以肯定地认为,复杂度中的log(n)来自二进制搜索,我将在最后一个中使用它。 However, that would mean I have to iterate over all possible combinations of 3 in n^2 time, which I just don't think is possible. 但是,这意味着我必须在n ^ 2时间内迭代3的所有可能组合,但我认为这是不可能的。

I'm not looking for someone to do my work for me, but maybe if someone knows how this can be solved, they could give me a gentle tap in the right direction. 我不是在找人为我工作,但是如果有人知道如何解决这个问题,他们可能会在正确的方向上为我提供一些帮助。 Thanks. 谢谢。

Edit: it might also be helpful to note that I am required to solve this using sorting. 编辑:注意到我需要使用排序解决此问题也可能会有所帮助。 Once I do that, I have to write another implementation that makes it faster using hashing, but I think I'll be able to do that just fine on my own. 一旦做到这一点,我就必须编写另一个使用散列来使其更快的实现,但是我想我自己就能做到这一点。 I just need to figure out how I can solve the problem with sorting first. 我只需要弄清楚如何首先解决排序问题即可。

Keep a sorted list of sums and pairs. 保留总和和对的排序列表。 For instance, given the list 例如,给定列表

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

we will want to identify 1+9 = 2+8 我们将要确定1+9 = 2+8

Identify the largest two numbers in the list, O**(N)**. 确定列表中最大的两个数字O **(N)**。 In this case, they're (82, 32), a sum of 114. Allocate an array pair_sum of 114 locations; 在这种情况下,它们是( pair_sum ),总和为114。分配一个数组对114个位置的pair_sum set all locations to null pointers. 将所有位置设置为空指针。

Now iterate through the list for your i, j pairs. 现在遍历您的i,j对的列表。 For each pair, insert the two numbers as a tuple-value at index i+j. 对于每对,将两个数字作为元组值插入索引i + j。 When you get a collision at some index, you're done: you found a second pair-sum. 当您在某个索引处发生冲突时,您就完成了:找到了第二对和。

I'll outline this in some not-quite-pseudo code; 我将以一些不太伪的代码来概述这一点。 you can translate to your favorite implementation language. 您可以翻译成自己喜欢的实现语言。

bank = [1, 2, 4, 8, 16, 32, 9, 82] size = length(bank) bank = [1、2、4、8、16、32、9、82]大小=长度(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])

This is O(N^2) , with bounded space dependent on the array values. 这是O(N ^ 2) ,有限空间取决于数组值。

If you aren't allowed to use the sum as an index for practical reasons, I think you can adapt this to a binary search and insertion, giving you the log(n) component. 如果出于实际原因不允许您将总和用作索引,我认为您可以将其用于二进制搜索和插入,并为您提供log(n)组件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM