3 回答
TA贡献1786条经验 获得超11个赞
对于k = 4,空间复杂度O(n),时间复杂度O(n 2 * log(n))
对数组进行排序。从最小的2个元素和最大lesser
的2个元素开始(a[i] + a[j])
,以非递减顺序计算2个元素的所有greater
和,(a[k] + a[l])
并以非递增顺序计算2个元素的所有和。lesser
如果总和小于零,则增加总和;如果总和大于零,则增加greater
一;如果总和为零(成功)或a[i] + a[j] > a[k] + a[l]
(失败),则停止。
诀窍是遍历所有索引,i
并且j
这种方式(a[i] + a[j])
永远不会减少。并且对于k
和l
,(a[k] + a[l])
永远不应该增加。优先级队列有助于实现此目的:
放入
key=(a[i] + a[j]), value=(i = 0, j = 1)
优先级队列。(sum, i, j)
从优先级队列中弹出。使用
sum
上述算法。把
(a[i+1] + a[j]), i+1, j
和(a[i] + a[j+1]), i, j+1
优先级队列仅如果不已经使用了这些元素。为了跟踪使用过的元素,请为每个“ i”维护一个最大使用的“ j”数组。仅使用大于“ i”的“ j”值就足够了。从步骤2继续。
对于k> 4
如果将空间复杂度限制为O(n),那么我将无法找到比将蛮力用于k-4
值并将上述算法用于剩余4
值更好的方法。时间复杂度O(n (k-2) * log(n))。
对于非常大的k
整数,线性规划可能会有所改善。
更新资料
如果n
非常大(与最大整数值相同的顺序),则可以实现O(1)优先级队列,从而提高O(n 2)和O(n (k-2))的复杂度。
如果为n >= k * INT_MAX
,则可以使用具有O(n)空间复杂度的其他算法。为所有可能的k/2
值之和预先计算一个位集。并使用它来检查其他k/2
值的总和。时间复杂度为O(n (ceil(k / 2)))。
添加回答
举报