【问题标题】:Find int that appears an odd number of times in an array查找在数组中出现奇数次的 int
【发布时间】:2019-06-16 18:51:49
【问题描述】:

我正在做这个任务,我需要找到一个在数组中出现奇数次的数字。

我相信我几乎已经完成了,但是如果某个数字连续出现多次(例如 [1,1,3,1,1] 中的 1),它将始终返回该数字,无论它是否出现奇数次与否。

function findOdd(A) {
  var a;
  var count = 0;
  for (var i = 0; i < A.length; i++) {
    a = A[i];
    for (var l = i + 1; l < A.length; l++) {
      if (a == A[l]) {
        count++;
      }
    }
    if (!(count % 2)) {
      break;
    } else {
      count = 0;
    }
  }
  return a;
}

console.log(findOdd([ 1, 1, 2, -2, 5, 2, 4, 4, -1, -2, 5 ]));

如果 [i] = [i+1],我尝试使用加 1 来计数,但没有奏效。

我希望findOdd([1, 1, 2, -2, 5, 2, 4, 4, -1, -2, 5]) 的输出是-1,但它是1。该函数总是返回恰好等于数组的下一个元素的第一个数字。

【问题讨论】:

  • @NinaScholz 也许我理解错了,但它不能是负数,我的输出应该不是计数,而是出现奇数次的整数,所以计数总是正数
  • 你的计数方式坏了。当您到达第二个1 时,您会计算在那之后有多少个,这是零。所以你的算法认为它只发生一次——奇数次。要按照您的方式执行此操作,您需要在两个循环中遍历整个数组。

标签: javascript


【解决方案1】:

无需重置计数或使用中断。

function findOdd(A) {
    for (var i = 0; i < A.length; i++){
        var count = 0;
        for (var l = 0; l < A.length; l++) {
            if (A[i] === A[l]) count++;
        }
        if (count % 2 !== 0) return A[i];
    }
}

需要注意的重要一点是,内部循环不是从i+1 开始的,而是从0 开始的。当A[i] 匹配A[l] 时,我们增加count。出现奇数次的数字将导致count 也变为奇数,我们可以返回该数字。

【讨论】:

    【解决方案2】:

    以下方法有效,但我想知道性能与简单地执行 for 循环相比如何。复杂度似乎是一样的。

    function findOdd(a) {
      let m = {};
    
      a.forEach(e => (m[e] in m) ? m[e] += 1 : m[e] = 1);
      for (k in m) {
        if (m[k] % 2 != 0) return k;
      }
    }
    
    console.log(findOdd([1, 1, 3, 1, 1]));
    console.log(findOdd([1, 1, 2, -2, 5, 2, 4, 4, -1, -2, 5]));

    【讨论】:

      【解决方案3】:

      您可以先计算所有值,然后获取奇数的值。

      function getOddCount(array) {
          var value,
              count = {},
              k;
      
          for (value of array) count[value] = (count[value] || 0) + 1;
          for (k in count) if (count[k] % 2) return +k;
      }
      
      console.log(getOddCount([1, 1, 3, 1, 1]));
      console.log(getOddCount([1, 1, 2, -2, 5, 2, 4, 4, -1, -2, 5]));

      【讨论】:

        【解决方案4】:

        一个简单的实现会简单地使用一个对象来存储每个元素的频率,然后在最后迭代它以找到出现奇数次的元素。

        function findOdd(arr) {
            const freq = {};
            for(const num of arr){
                freq[num] = (freq[num] || 0) + 1;
            }
            return +Object.keys(freq).find(num => freq[num] % 2 == 1);
        }
        

        更有效的实现可以利用按位异或 (^) 的属性,即 a ^ a == 0 和运算是可交换和关联的,从而导致对数组的每个元素应用异或的解决方案来获得答案。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-09-13
          • 2023-03-19
          • 2023-03-06
          • 2020-01-15
          • 1970-01-01
          • 2017-02-13
          • 1970-01-01
          • 2011-04-29
          相关资源
          最近更新 更多