给定一个列表,找到K个不同的元素,使得它们的和是S

时间:2016-02-16 02:07:22

标签: java algorithm

我知道当被要求找到两个加起来给定数字的元素时,可以在O(n)时间内获得解决方案,即通过制作散列图并在迭代列表时,只需找到一个元素a[j]=S - l[i]。我希望能够将此概括为K个不同的元素。我怎么会遇到这样的问题?递归,嵌套循环?我假设这种情况下最好的复杂性是O(n^{k-1}),这种直觉也是正确的吗?

2 个答案:

答案 0 :(得分:0)

该算法的直接改编如下:

在对列表进行迭代时,不要使用e找到一个S = e + l[i]元素,而是使用k查找e[j]个元素S = Sum e[j] + l[i]

sums <- HashMap<Number, Set<Number>>
put (0, { }) into sums  //we can achieve a sum of 0 with no element
for j from 1 to k - 1 //number of elements to use
    newSums <- HashMap<Number, Set<Number>>
    for i from 0 to n - 1
        for each entry (sum, elements) in sums //iterate every combination of j elements
        newSum <- l[i] + sum
        if not newSums contains newSum
            newSums.add (newSum, elements union { i })
    next
    swap(sums, newSums)
next
for i from 0 to n - 1
    lookingForSum <- S - l[i]
    if sums contains lookingForSum
        return sums[lookingForSum] union { i }
next

关键部分是sums可能变得非常大。在第一次迭代(k=1)之后,有n个不同的总和(如果所有条目都不同)。因此,第二次迭代运行n * n次,产生最多n * (n + 1) / 2个不同的总和(或O(n^2))。然后,第三次迭代运行n * O(n^2) = O(n^3)次,依此类推。所以整体时间复杂度确实是O(n^{k-1})

答案 1 :(得分:0)

编辑:我意识到以下算法也允许重复。所以,是的,我认为如果只需要考虑唯一元素,复杂性将增加到O(n^(k-1))

这个问题取决于k是偶数还是奇数。例如,将k视为3,即a + b + c = S,其中a,b,c属于该数组。通过蛮力,我们知道复杂性将是O(n^3)。但是,如果将所有数组元素存储在一个集合中,我们需要查找的是查看集合中是否存在S - (a + b)。这使我们O(n^2)复杂。

现在,如果您考虑k = 4,如果您意识到,您需要做的就是计算原始数组的所有2元素子集的总和的R(说得通?)。然后,对于原始数组中的每两个元素a和b,检查S-a-b是否在R中。这再次为O(n^2)提供了k = 4算法。

keven时,我们需要做的是:

  1. 确定一组R,用于存储原始数组的所有k/2-element tuples的所有总和。
  2. 对于原始数组中每个k/2个元组元组,计算其总和,比如说s。如果S - s ∈ R,则存在解决方案。
  3. 因此,复杂性为O(n^(k/2))

    kodd时,只需稍作修改即可。

    1. 第一步,原始数组的sums of all (k-1)/2 - tuples存储在R
    2. 对于原始数组中每个(k+1)/2个元组元组,计算其总和,比如说s。如果S - s ∈ R,则存在解决方案。
    3. 复杂性为O(n ^ (k+1)/2 )