Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用javascript使用算法解决问题_Javascript_Jquery_Arrays_Algorithm - Fatal编程技术网

使用javascript使用算法解决问题

使用javascript使用算法解决问题,javascript,jquery,arrays,algorithm,Javascript,Jquery,Arrays,Algorithm,我正在研究以下示例 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

我正在研究以下示例

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.
我使用了以下两种解决方案。但这两个数组的问题都是我在两个数组中循环。第一个I循环通过第一个数组并在该I循环内 通过第二个数组。在这两个指数上加上元素,看看它的加和是否等于答案。它工作正常,输出正确的答案。问题是 演出如果我们在两个数组中都有10000个整数,那么这些循环将占用大量资源,例如执行和获取答案所需的时间、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;
}

解决方案1
您可以使用较小的元素遍历数组的所有元素,直到answer,并在第二个数组中对
(answer-array[index])
进行二进制搜索,此算法的复杂性为
O(N log M)

解决方案2
或者,您可以在线性时间内合并两个数组,并应用以下算法在线性时间内查找该对。合并时,保留大小为
N+M
的反向映射数组mapA和mapB,其中mapA[i]指向从合并数组的第i个数组开始的数组A中的索引,否则为-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
/*合并阵列*/
mapA、mapB、MA都是大小为M+N的数组,初始化为all-1
i=0,j=0
而(i回答)j--;
}
返回空_对;//没有找到答案

解决方案3
有一种更好的算法(受三和算法启发)适用于线性时间,即恒定空间中的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
i=0
j=M-1
而(i=0){
if(A[i]+B[j]==应答)返回对(i,j);
如果(A[i]+B[j]<答案)i++;
否则如果(A[i]+B[j]>回答)j--;
}
返回空_对;//没有找到答案
证明
让我们假设
A[x]+B[y]=answer
。然后,
x
将首先到达
i
,或者
j
将首先到达
y
,或者我们将找到另一对,
A[i]+B[j]=答案
。在不丧失一般性的情况下,我们假设
x
首先变成
i
。现在对于所有的
j>y
A[i]+B[j]>答案
,所以j最终会得到答案。如果没有答案,我们将退出循环。

函数find(A1、A2、ans){
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;
}
var a=[]; 对于(变量i=0,len1=A1.length;i
//从数组a和b中获取a[i]+b[j]=和的所有数字对
//返回对数组
函数getSumPairs(a、b、sum){
var pa=0,pb=b.长度-1;
var对=[];
而(pa=0){
如果(a[pa]+b[pb]>和){
pb=pb-1;
}否则如果(a[pa]+b[pb]
该算法是将来自不同端的数组
a
b
的数据相加。阵列排序时:

如果
a[i]+b[j]
a[i]+b[j-1]
仍将小于
sum
,因此只需增加
i

如果
a[i]+b[j]>sum
a[i+1]+b[j]
仍将大于
sum
,因此只需减小
j

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


自己试试看

如果找不到匹配项会发生什么情况(例如,在您的示例中,答案=16)?那么它应该返回false/error。迭代第一个数组,然后在第二个数组中使用二进制搜索。时间复杂度为O(n logm)。您当前的时间复杂度为O(n*m)。二进制搜索将节省您的时间。这是一个jQuery问题吗?@Md.Yusuf它将是O(N log M)。我认为第一种方法的意思是O(N log M)。在线性时间中,它不是O(N+M)吗?如果较小数组的大小为N,则是。如果两个数组的大小相同,则为N log N。类似地,O(N+M)与O(N)具有相同的方式。但是你的观点是对的,我会更新它。while(I背后的原因是什么?如果您有两个数组
[1,2,3]
[10,17]
,并且您正在查找总和
13
,答案将是
i=2,j=0
,您的
while
循环将已经退出。我在下面放置了一个O(M+N)解决方案。Hi@MohitJain,对于您的两个输入,我已经运行了代码,它得到了[3,9],并且[9,3]分别。只需更改输入并调用
getSumPairs(arr1,arr2,12)
@GreenSu您可以用我的输入为其创建一个JSFIDLE吗?它对该输入不正常工作。我的意思是它对该输入不工作
var arr1=[-1,1,2,3,4,5,-7],arr2=[6,7,8,9,10,20,11];
。对于这一个
-7+20=13
,但它不会将其计算为true,也不会将其放入成对数组中。@26ph19作为问题
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;
}
// 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))