如何找出任何两个元素总和的子数组> K +

时间:2017-05-21 15:27:53

标签: arrays algorithm data-structures dynamic-programming subset-sum

上周末,我在接受采访时被问到这个问题。有一系列正数。从这个数组中,您需要找出子集。从这个子集中,您应该能够获取任意两个数字,并且它们的总和将始终大于k。 k是用户输入的值。

我能够在两次通过中解决这个问题。在第一遍中,我将拾取大于k的所有项并将它们放在子数组中。在这样做的同时,我将从该子集中找出最小值。

在下一遍中,我将按降序对数组进行排序。之后,我将通过将它们与子集中的最小数字相加来继续向子集添加数字。

上面提到的解决方案解决了这个问题。然而,时间复杂度将是O(n + nlogn)。然而,面试官希望它是O(n)。不用说我无法做到这一点。请帮我解决这个问题。我确实试图搜索互联网。但是我找不到任何具有o(n)时间复杂度的东西。

2 个答案:

答案 0 :(得分:3)

  • 将大于k/2的所有数字添加到子集中(跟踪最小值)。
  • 再次浏览数组并将任何大于k-minimum of subset的数字添加到子集中。我们添加1后停止。

    如果这是要求的一部分,您可以寻找最大的要求。

这在O(n)中运行。

这里的推理如下:

  • 任何2个元素> k/2的加起来都会超过k
  • 如果一个元素是<= k/2,则另一个元素需要> k/2才能加起来至少为k,因此不能有多个元素{{1 (如果有2个,那么2个加起来不会超过<= k/2)。

此示例为k,输出为k = 10, array = [3,4,8,9,10][3,8,9,10]。第一步会添加[4,8,9,10],然后我们会在第二步中添加8,9,103

技术说明:“子集”表示独特元素。我们可以使用哈希表来获得期望的(但不能保证)4复杂性。如果它是“子序列”(不是唯一元素),我们可以将它们添加到O(n)复杂度的数组或链表中。

答案 1 :(得分:0)

是的,可以用复杂度O(n)来解决它。在阵列上使用单个循环时,仅采用大于k / 2的数字。 一个简单的算法如下所示:

for(int i=0; i<n; i++){
    if(arr[i] > k/2.0){
         add arr[i] to the subset
    }
}