【问题标题】:Solve an issue using algorithm using javascript使用 javascript 使用算法解决问题
【发布时间】:2014-09-29 11:26:25
【问题描述】:

我正在研究以下示例

Given: 2 sorted arrays of integers(e.g. A = [1,2,3,4,5], B = [6, 7, 8, 9, 10]) and answer(e.g 13)
Find: What I have to do is to find pair of indices(1 in each array) of those two elements in both arrays so when I add them then it should be equal to the given answer.

我使用了以下 2 个解决方案。但是他们两个的问题是我正在循环遍历两个数组。首先,我遍历第一个数组并在其中循环 通过第二个数组。并在这两个索引上添加元素,看看它的添加是否等于答案。它工作正常并输出正确的答案。问题是 表现。如果我们在两个数组中都有 10,000 个整数,那么这些循环将占用大量资源,例如时间、CPU 和内存来执行并得到答案。

如何以更有效的方式解决上述特定问题?

function find (A1, A2, ans) {
  var a = [];
  for (var i = 0, len1 = A1.length; i < len1; i++) {
    for (var j = 0, len2 = A2.length; j < len2; j++) {
      if (ans === A1[i] + A2[j]) {
        a.push(i + ', ' + j);
      }
    }
  }
  return a;
}

function search (A, B, ans) {
  var arr = [];
  A.map(function (v, i) {
    B.filter(function (val, ind) {
      if (ans === v + val) arr.push(i + ', ' +ind);
    });
  });
  return arr;
}

【问题讨论】:

  • 找不到匹配项时会发生什么(例如您的示例中的 answer = 16)?
  • 那么它应该返回 false/error。
  • 迭代第一个数组并在第二个中使用二进制搜索。时间复杂度为 O(n log m)。您当前的时间复杂度为 O(n * m)。二进制搜索将节省您的时间。
  • 这是一个 jQuery 问题?
  • @Md.Yusuf 这将是 O(N log M)。

标签: javascript jquery arrays algorithm


【解决方案1】:

解决方案1
您可以遍历数组的所有元素,并在第二个数组中对(answer - array[index]) 进行二分搜索,该算法的复杂度为O(N log M)

Live code in C++

解决方案2
或者您可以在线性时间内合并两个数组并应用以下算法在线性时间内找到该对。合并时,保留大小为N+M 的反向映射数组 mapA 和 mapB,其中 mapA[i] 指向数组 A 中的索引,其中合并数组的第 ith 数组来自,否则为 -1。对 mapB 也进行类似操作。

/* Merge the arrays */
mapA, mapB, MA all are arrays of size M+N, initialized with all -1
i = 0, j = 0
while(i < M && j < N)
    if(A[i] < B[j])
        MA[i+j] = A[i];
        mapA[i+j] = i++;
    else
        MA[i+j] = B[j];
        mapB[i+j] = j++;
while(i < M)
    MA[i+j] = A[i];
    mapA[i+j] = i++;
while(j < N)
    MA[i+j] = B[j];
    mapB[i+j] = j++;

/* Search the pair */
i = 0
j = N + M - 1
while(i < j){
   if(mapA[i] == -1) i++;
   else if(mapB[j] == -1) j--;
   else if (MA[i] + MA[j] == answer) return pair(mapA[i], mapB[j]);
   else if (MA[i] + MA[j] <  answer) i++;
   else if (MA[i] + MA[j] >  answer) j--;
}
return null_pair;  // no answer found

Live code example in C++

解决方案3
有一种更好的算法(灵感来自 3 sum 算法),它可以在线性时间内工作,即 O(N + M) 在恒定空间中。

i = 0
j = M - 1
while(i < N && j >= 0){
   if      (A[i] + B[j] == answer) return pair(i, j);
   else if (A[i] + B[j] <  answer) i++;
   else if (A[i] + B[j] >  answer) j--;
}
return null_pair;  // no answer found

证明
让我们假设A[x] + B[y] = answer。然后x 将首先到达i,或者j 将首先到达y,或者我们将找到其他一些配对,例如A[i] + B[j] = answer。不失一般性,让我们假设x 首先变为i。现在对于所有j &gt; yA[i] + B[j] &gt; answer,所以 j 最终会得到答案。如果没有答案,我们将退出循环。

【讨论】:

  • 我认为你的意思是第一种方法的 O(N log M)。
  • 在线性时间内也不会是 O(N + M) 吗?
  • 如果较小数组的大小为 N,则为是。如果两个数组的大小相当,则为 N log N。同样,O(N+M) 与 O(N) 类似。但你的观点是对的,我会更新它。
  • while (i &lt; j) 背后的原因是什么?如果您有两个数组 [1, 2, 3][10, 17] 并且您正在寻找总和 13,则答案将在 i = 2, j = 0 并且您的 while 循环已经退出。
  • 我在下面放了一个 O(M+N) 的解决方案。
【解决方案2】:
// get all pairs of number from array a and b, that a[i] + b[j] = sum
// return array of pairs
function getSumPairs(a, b, sum) {
    var pa = 0, pb = b.length - 1;
    var pairs = [];
    while (pa < a.length && pb >= 0) {
        if (a[pa] + b[pb] > sum ) {
            pb = pb - 1;
        } else if (a[pa] + b[pb] < sum) {
            pa = pa + 1;
        } else {
            pairs.push([a[pa], b[pb]]);
            pa = pa + 1;
            pb = pb - 1;
        }
    }
    return pairs;
}


// data for test
var arr1 = [-1, 1, 2, 3, 4, 5, 7, 9],
    arr2 = [5, 7, 10, 12, 13, 14, 15];

console.log(getSumPairs(arr1, arr2, 14))
console.log(getSumPairs(arr1, arr2, 15))

算法是将数组ab不同端的数据相加。随着数组的排序:

如果a[i] + b[j] &lt; suma[i] + b[j-1]仍会小于sum,所以只需增加i即可。

如果a[i] + b[j] &gt; suma[i+1] + b[j] 仍会大于sum,所以只需减小j

因此,来自两个数组的所有元素只循环一次。复杂度为O(M + N),对于a[N] 和b[M]。

自己试试http://jsfiddle.net/9L4p1j3L/

【讨论】:

  • 嗨@MohitJain,对于您的两个输入,我已经运行了代码,它分别得到 [3,9] 和 [9, 3]。只需更改输入并致电getSumPairs(arr1, arr2, 12)
  • @GreenSu 你能用我有问题的输入为此创建一个 jsfiddle 吗?它不适用于该输入。
  • 我的意思是它不适用于这个输入var arr1 = [-1, 1, 2, 3, 4, 5, -7], arr2 = [6, 7, 8, 9, 10, 20, 11];。对于这个-7+20=13,但它不会将其评估为真,也不会放入对数组中。
  • @26ph19 正如问题所述,输入应该是两个sorted array。所以你的输入是无效的。 arr1 应该是 [-7, -1, 1, 2, 3, 4, 5]
  • @26ph19 和arr2[6, 7, 8, 9, 10, 11, 20]
【解决方案3】:
function find (A1, A2, ans) {
  var a = [];
  for (var i = 0, len1 = A1.length; i < len1; i++) {
    var noToSearch = ans - A1[i];
    var secondIndex  = binarySearch(A2,noToSearch);
    if(secondIndex !=-1){
        a.push(i + ', ' + secondIndex );
    }
  }
  return a;
}

function binarySearch(A2,num){
 var index = -1;
  //write binary search algo to find the element in array A2
 return index;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-22
    • 2021-06-14
    • 1970-01-01
    • 2015-12-04
    • 2021-04-03
    • 2021-12-04
    • 1970-01-01
    相关资源
    最近更新 更多