最小的" n"来自n个数组的总和

时间:2016-03-29 23:55:20

标签: arrays algorithm sum

我几年前试图做我的朋友问题集来提高我对数据结构的了解等等。我遇到了这个问题,而且我不确定从哪里开始。希望有人可以帮助我!

我们给出n个未排序的数组,每个数组有n个元素。实施例

3 1 2
7 6 9
4 9 12

现在,假设我们从每个数组中取出一个元素,并将它们相加。让我们将这些元素的总和称为" n-sum"。

我需要设计一种算法,为我们提供n个最小的" n-sums" (允许重复)。

在上面的例子中,答案是:

11, 12, 12

# 11 comes from: 1 (first array) + 6 (second array) + 4 (third array)
# 12 comes from: 2 (first array) + 6 (second array) + 4 (third array)
# 12 comes from: 1 (first array) + 7 (second array) + 4 (third array)

给出的建议之一是使用优先级队列。

谢谢!

1 个答案:

答案 0 :(得分:2)

时间至少为O(n ^ 2):您必须访问所有数组元素,因为如果所有元素都等于1000,除非每行为0,则必须查看等于0的n个元素,或者你找不到最小的金额。

对每一行进行排序,采用O(n ^ 2 log n)步。在每一行中,从行中的所有元素中减去第一个元素,因此每行中的第一个元素为0;在找到最小的金额后,你可以弥补这一点。你的例子变成了

3 1 2  -> 1 2 3 -> 0 1 2
7 6 9  -> 6 7 9 -> 0 1 3
4 9 12 -> 4 9 12-> 0 5 7

现在找到所有和≤K可以以m步进行,如果有m个和:在第一行中,只要它们≤K,就依次选择所有值。在第二行中,依次选择所有值两行的总和≤K,依此类推。由于每行以0开头,因此不会浪费时间。

例如,和≤5是:0 + 0 + 0,0 + 0 + 5,0 + 1 + 0,0 + 3 + 0,1 + 0 + 0,1 + 1 + 0,1 + 3 + 0,2 + 0 + 0,2 + 1 + 0,2 + 3 + 0。我们需要的不仅仅是三个。如果我们在找到3个总和≤5后停止,我们很快就知道“至少有3个总和≤5”。我们需要提前停止,因为在一般情况下可能有n ^ n个可能的总和。

如果您选择K =“第二列中的最大元素”,那么您知道至少有n + 1个和值≤K,因为您可以选择全0或全0,除了第二个值中的一个值柱。在你的例子中,K = 5(我们知道这很有效)。设X是n和n≤X但小于n和≤X-1的值。我们在0到K之间找到二进制搜索的X,然后我们找到总和。示例:

已知K = 5足够大。我们尝试K = 2,找到4个总和(实际上我们停在3个总和)。太多。我们尝试K = 1,并且有三个解0 + 0 + 0,0 + 1 + 0和1 + 0 + 0。我们尝试K = 0,但只有一个解决方案。

这部分非常快,所以我们尝试减少用于排序的时间。我们注意到在这种情况下,查看前两列就足够了。我们可以在每一行中找到两个最小的项目,在这种情况下,这就足够了。如果两个最小的项目不足以确定n个最小的总和,则在需要的地方找到第三个最小的项目等。例如,由于最后一行的第二大项是5,我们不需要该行的第三项,因为如果K≤4,即使5也不是和的元素。