JS:在数组中查找未配对的元素

时间:2018-08-21 06:45:33

标签: javascript

我有以下问题(这不是学校-只是代码站点练习问题),我看不到我的解决方案缺少什么。

给出了一个由N个整数组成的非空数组A。数组包含奇数个元素,并且该数组的每个元素都可以与另一个具有相同值的元素配对,除了一个未配对的元素。

假设:

  • * N是[1..1,000,000]范围内的奇数整数;
  • *数组A的每个元素都是[1..1,000,000,000]范围内的整数;
  • **除A中的一个值外,所有其他值均出现偶数次。

EX:A = [9,3,9,7,9] 结果:7

官方解决方案是使用按位XOR运算符:

function solution(A) {

    var agg = 0;

    for(var i=0; i<A.length; i++) {
        agg ^= A[i];
    }

    return agg;
}

我的第一个直觉是在Map查找表中跟踪每个值的出现,并返回唯一值仅出现一次的键。

function solution(A) {

    if (A.length < 1) {return 0}
    let map = new Map();
    let res = A[0]
    for (var x = 0; x < A.length; x++) {
        if (map.has(A[x])) {
            map.set(A[x], map.get(A[x]) + 1)
        } else {
            map.set(A[x], 1)
        }
    }
    for ([key,value] of map.entries()) {
        if (value===1) {
            res = key
        } 
    }

    return res;
}

我觉得我处理了所有极端情况,但我仍未通过某些测试,并且自动计分器的正确率达到了66%。

5 个答案:

答案 0 :(得分:5)

您可以使用http://sqlfiddle.com/#!18/648d0/7并检查是否删除删除了一项。如果没有,则将值添加到集合中。

function check(array) {
    var s = new Set;
    
    array.forEach(v => s.delete(v) || s.add(v));
    
    return s.values().next().value;
}

console.log(check([9, 3, 9, 7, 3, 9, 9])); // 7

答案 1 :(得分:2)

您没有考虑以下情况:

[ 1, 1, 2, 2, 2 ] => the last 2 is left unpaired

因此您的情况应该为if ( value % 2 ),而不是if ( value === 1 )

我认为使用Map而不只是普通对象并没有太大好处。

答案 2 :(得分:0)

如果您确定将有exactly one次出现odd的次数,则无需对每个进行计数并再次遍历。您可以对数组求和并在出现奇数输入时执行+,而在偶数输入时执行-(将其撤消),并且在哈希(映射或对象)中,只需切换每个数字的后续输入即可。

这里是一个例子:

let inputArray1 = [10,20,30,10,50,20,20,70,20,70,50, 30,50], //50 -> 3 times
    inputArray2 = [10,20,30,20,10], //30 -> 1 time
    inputArray3 = [7,7,7,7,3,2,7,2,3,5,7]; //5 -> 1 time

let getOddOccuence = arr => {
  let hash = {};
  return arr.reduce((sum, n) => sum + ((hash[n] = !hash[n]) ? n : -n), 0);
}

console.log('Input Array 1: ', getOddOccuence(inputArray1));
console.log('Input Array 2: ', getOddOccuence(inputArray2));
console.log('Input Array 3: ', getOddOccuence(inputArray3));

如果输入包含多个或不存在奇数个数字(如果不确定),则您已经有hash(并且可以忽略执行sum)并返回哈希键(值是true(并且不与%2进行核对,如果有计数,则视为真或假))

答案 3 :(得分:0)

function solution(A) {
    let result = 0;
  
    for (let element of A) {
        // Apply Bitwise XOR to the current and next element
        result ^= element;
    }

    return result;
}

const unpaired = solution([9, 3, 9, 3, 9, 7, 9]);

console.log(unpaired);

来源:https://gist.github.com/k0ff33/3eb60cfb976dee0a0a969fc9f84ae145

答案 4 :(得分:0)

由于按位XOR(^)的属性,即a ^ a == 0a ^ 0 == a以及运算是可交换和关联的事实,因此官方解决方案有效。这意味着数组中的任何两个相等元素将互相抵消而变为零,因此所有出现偶数次的数字都将被删除,仅保留频率为奇数的数字。可以使用Array#reduce简化解决方案。

function findOdd(arr) {
    return arr.reduce((a,c)=>a ^ c, 0);
}