总和至少为 K 的最小数字集

Posted

技术标签:

【中文标题】总和至少为 K 的最小数字集【英文标题】:Minimum set of numbers that sum to least K 【发布时间】:2013-01-21 01:59:09 【问题描述】:

给定一个包含 n 个对象的列表,编写一个函数,输出。跟进:你能打败 O(n ln n) 吗?

最小集合将是一个包含 1 个元素的集合。难道我们只需要遍历数组并找到一个元素,即 >= K。

否则对于 O(nlgn),我知道我们必须首先对数组进行排序,然后我们才能找到总和 >=k 的对或三元组。 如果我们没有找到这样的组合,必须去更大的集合,这个问题会不会和 N sum 问题一样?

【问题讨论】:

@Pavan..不,这不是..这是一个面试问题..不幸的是,我没有得到“面试”标签,所以无法标记它。 【参考方案1】:

这是一个使用线性时间中位数查找作为子程序的线性算法:

Findsum(A, K) 
  Let n be the length of A.
  Let M be the median element of A, found in linear time.
  Let L be the elements of A less than M.
  Let U be the elements of A greater than M.
  Let E be the elements of A equal to M.
  If the sum of the elements in U is at least K,
    Return Findsum(U, K).
  Else, if the sum of the elements in U and E is at least K,
    Return U together with enough elements of E that the sum is at least K.
  Else,
    Return Findsum(L, K - sum(U) - sum(E)).

每个递归调用最多在一个大小为 A 一半的列表上完成,所有其他步骤最多花费线性时间,因此该算法总体上花费线性时间。

【讨论】:

你确定这是线性算法吗? 是的。你得到一个看起来像 T(n) n 的循环,它给你绑定 T(n) n。 很好,但您不是说 L、U 和 E 的定义中的 M 而不是 A[i] 吗? @tmyklebu。当你说“元素的总和”时......你的意思是添加范围内的所有元素吗?能稍微解释一下算法吗? @user1071840:U 和 E 是数字列表。 U 和 E 中的元素之和为 U[0] + U[1] + ... + U[U.size-1] + E[0] + E[1] + ... + E[E .size-1].【参考方案2】:

这与 N Sum 问题非常不同,因为它要求集合加起来至少 K,而不是恰好 K。

可以在 O(n ln n) 内完成,通过对列表进行排序并从最大元素开始直到总和大于 K。可以通过先扫描列表进行优化,以消除单个数字的情况 > K 和所有成员的总和

可以使用索引数组(或整数列表)进行排序,因此不需要移动原始值或对象。

【讨论】:

以上是关于总和至少为 K 的最小数字集的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 334. 递增的三元子序列 / 747. 至少是其他数字两倍的最大数 / 373. 查找和最小的K对数字(多路归并滑动窗口+二分)

如何找到从多个数组中提取的数字的最小总和?

216. 组合总和 III

216. 组合总和 III

leetcode 216. 组合总和 III

Leetcode No.216 组合总和 III