如果给定arr1 [1、2、3]和arr2 [2、4],我需要找出arr1中有多少个元素小于或等于arr2中的每个元素。对于这些数组,输出应为[2,3],因为arr1中的2个元素小于或等于arr2 [1],arr1中的3个元素小于或等于arr2 [2]。
我已经天真地解决了这个问题,但是我想降低运行时的复杂性-这种解决方案根本不能很好地处理大型数组。谁能阐明我如何重构它以减少复杂性?
counts([1, 2, 3] ,[2, 4])
function counts(nums, maxes) {
let newArr = [];
for(let i = 0; i < maxes.length; i++){
let count = 0;
for(let j = 0; j < nums.length; j++){
if(nums[j] <= maxes[i]){
count++;
}
}
newArr.push(count);
}
console.log(newArr);
}
答案 0 :(得分:1)
我将从对第一个数组进行排序开始。然后,对于第二个数组中的每个元素,使用二进制搜索找到将其插入第一个数组的位置(但实际上不插入它)。该索引将告诉您第一个数组中有多少个元素小于或等于第二个数组中的那个元素。将其附加到结果数组,然后继续。这具有O(n log n)的复杂度,其中n是较大数组的大小。
counts([1, 2, 3] ,[2, 4])
function counts(nums, maxes) {
nums.sort();
let result = [];
for(let i = 0; i < maxes.length; i++){
let index = binarySearch(maxes[i], nums);
result.push(index);
}
console.log(result);
}
我没有在此处包含binarySearch
的代码,但是它将在O(log n)时间内找到nums
中最小项的索引大于maxes[i]
。有关二进制搜索,请参见Wikipedia article。
答案 1 :(得分:1)
var res = arr2.map(x => arr1.filter(elem => elem<=x).length);
答案 2 :(得分:1)
这是一种不同的方法,首先对两个数组(或副本)进行排序,然后对索引变量进行闭包,然后将最后找到的索引(加一个)映射到相应的搜索值。
结果实际上是与Map
一起使用的计数的排序数组。然后返回映射的索引。
function fn(a, b) {
const
ASC = (a, b) => a - b;
var indices;
a.sort(ASC);
indices = new Map(
b.slice().sort(ASC).map((i => v => {
while (i in a && a[i] <= v) ++i;
return [v, i];
})(0))
);
return b.map(v => indices.get(v));
}
console.log(fn([1, 2, 3], [2, 4]));
答案 3 :(得分:0)
查看二进制搜索,基本上您可以减少每一步的馆藏。 Binary Search
答案 4 :(得分:0)
您可以尝试此方法
const comapreArrays = (arr1,arr2) => {
return arr1.map(numInFirstArray => arr2.filter(numInSecArray =>
numInFirstArray <= numInSecArray).length);
}
答案 5 :(得分:0)
var arr1=[1,5,3];
var arr2=[2,4];
var res = arr2.map(element=>{
var count=0;
arr1.forEach(function(i){
if(i<=element)
count++;
});
return count;
});
alert(res);