使用javascript使用算法解决问题
Solve an issue using algorithm using javascript
我正在研究以下示例
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;
}
解决方案1
你可以遍历数组的所有元素,用较少的元素直到答案和二进制搜索第二个数组(answer - array[index])
,这个算法的复杂性是O(N log M)
。
C++中的实时代码
解决方案2
或者,您可以在线性时间内合并两个数组,并应用以下算法来查找线性时间中的数组对。合并时,保留大小为 N+M
的反向映射数组 mapA 和 mapB,其中 mapA[i] 指向数组 A 中的索引,从第 i个合并数组的数组中出现,否则为 -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
C++中的实时代码示例
解决方案3
有一种更好的算法(灵感来自 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
证明
让我们假设A[x] + B[y] = answer
.然后,要么x
首先到达i
,要么j
将首先到达y
,或者我们会找到其他一对这样A[i] + B[j] = answer
.在不失去一般性的情况下,让我们假设x
首先成为i
。现在对于所有j > y
,A[i] + B[j] > answer
所以j最终会得到答案。如果没有答案,我们将退出循环。
// 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))
该算法是对数组a
中的数据求和,并从不同端b
。当数组排序时:
如果a[i] + b[j] < sum
,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)
。
自己尝试 http://jsfiddle.net/9L4p1j3L/
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;
}
- 如何解决Yii中的页面刷新问题
- 简单的ES6承诺问题-交换解决和拒绝参数
- 为什么不'我的窗口滚动事件根本没有启动.其他答案没有解决问题
- 当服务器从 http 更改为 https 时,有哪些可能的方法可以解决问题
- 如何使用共享按钮将所有内容对齐到一行来解决问题
- 使用 unity,我的 js 文件无法解决问题
- 缺少 iframe ie8.相对定位不能解决问题
- 如何删除给定字符串中的 CRLF 以解决问题
- 为什么 标记将空格替换为 %2520?如何解决问题
- 使用javascript使用算法解决问题
- 请解决问题在我的AJAX脚本的联系形式
- Angular Js ->UI -路由->解决问题
- 关于RSA填充算法的问题
- 运动:rna转录.正在努力解决问题
- JQuery addClass不透明度函数淡入图像-解决问题
- 如何通过程序解决问题
- JavaScript Promise在解决问题时陷入困境
- Chrome文件夹上传API.检测支持&使用JS/JQuery解决问题
- Angular js :$q解决问题
- 由于Node的异步特性,需要帮助解决问题