在Javascript

时间:2018-03-15 18:47:53

标签: javascript arrays algorithm

我正在解决在两个数组中找到公共数字的问题。

我的第一个方法是:

    const findCommonNumbers = (array1,array2) => {

    const map = array1.reduce((accum, element)=>{
        accum[element] = true;
        return accum;
    } , {});

    const result = [];
    array2.forEach((e)=>{
        if (map[e]) {
            result.push(e);
        }
    });
    return result;
}

const array1 = [4, 2, 3, 6, 23];
const array2 = [3, 2, 4, 7 ,9];



const result = findCommonNumbers(array1, array2 );
console.log('result', result);

然而,看看解决方案,最有效的方式似乎是:

const findCommonNumbers = (array1, array2) => {

    const result = [];
    let p1 = 0;
    let p2 = 0;
    while (p1 < array1.length  && p2 < array2.length) {
        const e1 = array1[p1];
        const e2 = array2[p2];

        if (e1 === e2) {
            result.push(e1);
            p1++;
            p2++;
        }
        else if (e1 < e2) {
            p1++;
        }
        else {
            p2++;
        }
    }

    return result;
}

const array1 = [2, 3, 4, 6, 23];
const array2 = [2, 3, 4, 7, 9];


const result = findCommonNumbers(array1, array2);
console.log('result', result);

但是,我发现在这两种情况下,两个数组都被迭代一次,此外,我的初始解决方案也适用于未排序的数组。 两种算法的复杂性是什么?为什么? 提出的解决方案是否因为两个数组在同一个循环中迭代这一事实而更有效率,而在我的情况下,我是按顺序迭代它们?

1 个答案:

答案 0 :(得分:0)

一线解决方案:

a1.filter(n => a2.includes(n));

包装功能:

const findCommonNumbers = (a1, a2) => a1.filter(n => a2.includes(n));

或者当我们想要通过&#39; n&#39;数组和查找公共数字

const findCommonNumbers = (...a) => [...a].reduce((p,c) => p.filter(e => c.includes(e)));

效果

我运行简单的基准测试来比较性能(i5-7500 3,4GHz,16GB ram,windows 10,NodeJS v9.8.0)

smallArray length = 10;
bigArray length = 10000;

和一些结果:

CASE1: (a1, a2) => a1.filter(n => a2.includes(n)), INPUT(smallArr,BigArr)
1: 0.892ms
CASE2: (a1, a2) => a1.filter(n => a2.includes(n)), INPUT(bigArr,smallArr)
2: 2.088ms
CASE3: (...a) => [...a].reduce((p,c) => p.filter(e => c.includes(e))), INPUT(smallArr,BigArr)
3: 0.968ms
CASE4: (...a) => [...a].reduce((p,c) => p.filter(e => c.includes(e))), INPUT(bigArr,smallArr)
4: 1.712ms
CASE5: fgonzalez code, INPUT(smallArr,BigArr)
5: 1.090ms
CASE6: fgonzalez code, INPUT(bigArr,smallArr)
6: 0.989ms


CASE1: (a1, a2) => a1.filter(n => a2.includes(n)), INPUT(smallArr,BigArr)
1: 0.908ms
CASE2: (a1, a2) => a1.filter(n => a2.includes(n)), INPUT(bigArr,smallArr)
2: 2.227ms
CASE3: (...a) => [...a].reduce((p,c) => p.filter(e => c.includes(e))), INPUT(smallArr,BigArr)
3: 0.968ms
CASE4: (...a) => [...a].reduce((p,c) => p.filter(e => c.includes(e))), INPUT(bigArr,smallArr)
4: 1.588ms
CASE5: fgonzalez code, INPUT(smallArr,BigArr)
5: 1.058ms
CASE6: fgonzalez code, INPUT(bigArr,smallArr)
6: 0.987ms


CASE1: (a1, a2) => a1.filter(n => a2.includes(n)), INPUT(smallArr,BigArr)
1: 1.014ms
CASE2: (a1, a2) => a1.filter(n => a2.includes(n)), INPUT(bigArr,smallArr)
2: 2.167ms
CASE3: (...a) => [...a].reduce((p,c) => p.filter(e => c.includes(e))), INPUT(smallArr,BigArr)
3: 0.991ms
CASE4: (...a) => [...a].reduce((p,c) => p.filter(e => c.includes(e))), INPUT(bigArr,smallArr)
4: 1.642ms
CASE5: fgonzalez code, INPUT(smallArr,BigArr)
5: 1.161ms
CASE6: fgonzalez code, INPUT(bigArr,smallArr)
6: 1.063ms


CASE1: (a1, a2) => a1.filter(n => a2.includes(n)), INPUT(smallArr,BigArr)
1: 0.941ms
CASE2: (a1, a2) => a1.filter(n => a2.includes(n)), INPUT(bigArr,smallArr)
2: 2.262ms
CASE3: (...a) => [...a].reduce((p,c) => p.filter(e => c.includes(e))), INPUT(smallArr,BigArr)
3: 0.989ms
CASE4: (...a) => [...a].reduce((p,c) => p.filter(e => c.includes(e))), INPUT(bigArr,smallArr)
4: 1.603ms
CASE5: fgonzalez code, INPUT(smallArr,BigArr)
5: 1.080ms
CASE6: fgonzalez code, INPUT(bigArr,smallArr)
6: 1.178ms

当smallArr是第一个arg时,我的代码稍快一些。 当bigArr是第一个arg时,@ fgonzalez代码快2倍。