我知道当被要求找到两个加起来给定数字的元素时,可以在O(n)
时间内获得解决方案,即通过制作散列图并在迭代列表时,只需找到一个元素a[j]=S - l[i]
。我希望能够将此概括为K
个不同的元素。我怎么会遇到这样的问题?递归,嵌套循环?我假设这种情况下最好的复杂性是O(n^{k-1})
,这种直觉也是正确的吗?
答案 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
算法。
在k
为even
时,我们需要做的是:
R
,用于存储原始数组的所有k/2-element tuples
的所有总和。k/2
个元组元组,计算其总和,比如说s
。如果S - s ∈ R
,则存在解决方案。因此,复杂性为O(n^(k/2))
当k
为odd
时,只需稍作修改即可。
sums of all (k-1)/2 - tuples
存储在R
。(k+1)/2
个元组元组,计算其总和,比如说s
。如果S - s ∈ R
,则存在解决方案。复杂性为O(n ^ (k+1)/2 )