求解数组值的总和在“kn”而不是“n ^ 2”时间内练习

时间:2014-01-22 05:48:38

标签: javascript algorithm data-structures

我有以下功能:

function myFunction(array, sum){
     for(var i = 0; i < array.length; i++){
          var firstValue = array[i];
              for(var x = i + 1; x < array.length; x++){
                    var secondValue = array[x];
                    if((firstValue + secondValue) == sum){
                        return i + ": " + x; 
                    }
              }
     }
     return "No two array values match the sum";
}

以上有两个参数;第一个是数组,第二个是数组。它找到数组中的前两个数字,当它们加到第二个参数时。然后返回与第二个参数相加的两个数字的数组索引。现在,上面的函数解决了n^2时间内的问题。有没有办法在kn时间内解决同样的问题?

我在JavaScript中编写了这个函数,但这可以应用于所有现代语言。

3 个答案:

答案 0 :(得分:1)

对于这个问题,有两种方法,它们都基于有序数组的属性。

第一步,对数组进行排序,这需要 O(nlogn )时间复杂度。

第二步:

  • 方法A:遍历排序数组中的每个值array[i],使用二进制搜索在此数组值中查找:sum - array[i]。此步骤的时间复杂度为 O(nlogn)(如果我们限制搜索范围从i开始,则甚至为O(n))

  • 方法B:维持两个指针,数组开头的start点(最小值)和数组末尾的end点(最大值)。因此,我们会逐个增加start的值,直到start不再小于end。对于start指向的每个值,我们将值sum - array[start]array[end]进行比较。如果值array[end] > sum - array[start],我们减少结束,否则如果array[end] < sum - array[start],则返回null。此步骤的时间复杂度为 O(n)

总的来说,这两种方法都给出了O(nlogn)时间复杂度。

答案 1 :(得分:1)

这是2和问题。通常,这个问题有2种有效的算法。

1)哈希方法,你为每个值和每个值v创建一个哈希表,只需查找sum-v。

function myFunction(array, sum){
 hash h;
 for(var i = 0; i < array.length; i++){
      if (h.find(sum-array[i])) return "found";
      h.insert(array[i]);
 }
 return "No two array values match the sum";

}

时间和空间复杂度都是O(N)。

2)另一种方法是先对数组进行排序,然后使用2索引进行查找。

function myFunction(array, sum){
     sort(arrary);
     var i = 0, j = array.length-1;
     while (i < j) {
       if (array[i] + array[j] == sum) return "Found";
       else if (array[i] + array[j] > sum) --j;
       else ++i;
     }
     return "No two array values match the sum";
   }

花费O(NlnN)时间和O(1)空间。

要返回值的2索引,您应该将索引存储在哈希表和您排序的数组中。

答案 2 :(得分:0)

我不确定k是什么意思,但如果k代表总和,并且数组只包含非负整数,那么你可以在O(k * n)时间内完成。当k <&lt;&lt; n,它具有O(1)额外内存的好处,并且不修改原始数组。

想法是使用i = 0..k扫描数组k + 1次。在每次扫描时,搜索值i和k-i。如果两者都找到了,请返回他们的位置。如果所有k + 1扫描完成且没有匹配,则无法实现总和。