我有以下功能:
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中编写了这个函数,但这可以应用于所有现代语言。
答案 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扫描完成且没有匹配,则无法实现总和。