返回数组中的第一个重复数字

时间:2017-09-01 19:45:38

标签: javascript arrays algorithm array-algorithms

我正在尝试解决一个简单的挑战,我在其中编写一个函数,在数组中返回第一个重复数字。

这就是我的尝试:

function duplicateNumber(arr) {
    for (var i = 0; i < arr.length; i++) {
        for (var j = arr.length; j >= 0; j--) {
            if (arr[i] === arr[j]) {
                var dup_num = arr[i]
            }
        }
    }
    return dup_num
}

它似乎不起作用。我做错了什么?

刚刚意识到我也是从头到尾循环开始结束。

数组中的

= [3, 5, 6, 8, 5, 3]

重复的数字应为5,因为它在3之前重复。

8 个答案:

答案 0 :(得分:5)

在ES2015中,它真的和

一样简单
let dupe = arr.find((k,i) => arr.lastIndexOf(k) !== i);

你只需检查索引,看看在这个索引之前是否有相同值的索引,在这种情况下,它将是第一个 找到 重复

&#13;
&#13;
function duplicateNumber(arr) {
	return arr.find((k,i) => arr.indexOf(k) !==i);
}

console.log( duplicateNumber([3, 5, 6, 8, 5, 3]) ) // 5 (not 3)
console.log( duplicateNumber([1, 2, 3, 1, 2, 3]) ) // 1
console.log( duplicateNumber([1, 2, 3, 4, 4, 2]) ) // 4 (not 2)
&#13;
&#13;
&#13;

没有ES2015

&#13;
&#13;
function duplicateNumber(arr) {
  var item = null;

  for (var i = 0; i < arr.length; i++) {
    if (arr.lastIndexOf(arr[i]) !== i) {
      item = arr[i];
      break;
    }
  }

  return item;
}

console.log(duplicateNumber([3, 5, 6, 8, 5, 3])) // 5
console.log(duplicateNumber([1, 2, 3, 1, 2, 3])) // 1
console.log(duplicateNumber([1, 2, 3, 4, 4])) // 4
&#13;
&#13;
&#13;

答案 1 :(得分:2)

您可以在结束前迭代元素,并从i + 1开始检查直到结束。

此函数仅返回第一个副本。

带有一个循环和哈希表的快速版本。

style.css

答案 2 :(得分:1)

你的内部循环遍历到0。相反,它应该只下降到i+1,以便它不会遇到外部循环中的当前字符,使它认为它找到了重复。

此外,你的内部循环应该从arr.length-1开始是正确的,这样它就不会测试越界索引。

代码已更新,以反映问题中的更改

function duplicateNumber(arr) {
  var idx = arr.length;

  OUTER:
  for (var i = 0; i < idx; i++) {
    for (var j = idx-1; j >= i+1; j--) {
      if (arr[i] === arr[j]) {
        idx = j
        continue OUTER
      }
    }
  }
  return arr[idx]
}

console.log(duplicateNumber([3, 5, 6, 8, 5, 3]));

当找到副本时我也立即返回,因为没有理由继续循环应该在那时停止,这样你就不会用稍后的副本覆盖你的结果。

如果未找到重复项,则返回undefined

根据更新的要求,我们存储重复索引的索引,然后继续。如果找到另一个副本,它将替换当前存储的副本。

内部循环始终从最后找到的索引之前的索引处开始,并且遍历到i+1,因为我们不关心最后找到的索引之上的索引。

答案 3 :(得分:1)

您不需要第二个循环,可以使用Array.prototype.indexOf()。此外,您可以减少代码行并立即返回结果。例如:

function duplicateNumber(arr) {
  for (var i = 0; i < arr.length; i++) {
    if (arr.indexOf(arr[i]) !== i) {
      return arr[i];
    }
  }
  return null;
}

console.log(duplicateNumber([3, 5, 6, 8, 5, 3]));

答案 4 :(得分:0)

function getFirstDupe(arr){
  var dupe;

  if(arr && arr.forEach){
    arr.forEach(function(item, index){
      if(dupe === undefined && arr.indexOf(item) !== index){
        dupe = item;
      }
    })
  }

  return dupe;
}

答案 5 :(得分:0)

只是一种替代方法,您可以使用对象来存储计数

function duplicateNumber(arr) {
    let count = {};
    for (var i = 0; i < arr.length; i++) {
        count[arr[i]] = (count[arr[i]] || 0) + 1;
        if(count[arr[i]] > 1){
            return arr[i];
        }
    }
    return dup_num
}

console.log(duplicateNumber([0, 1, 1, 2, 3, 4, 4, 5]));

答案 6 :(得分:0)

如果您想在最短的时间内完成此操作。我会建议这样的事情。这将在最坏的情况下完成O(n);

function duplicateNumber(arr) {
  var memory = {};
  for (var i = 0; i < arr.length; i++) {
    if(memory[arr[i]] === undefined){
      memory[arr[i]] = true;
    }else{
      return arr[i]
    }
  }
}

var arr = [2,3,2,3];
console.log(duplicateNumber(arr));

答案 7 :(得分:0)

详细说明spanky所说的:用你的解决方案,你将在某一点上总是最终将arr [i]与arr [j]进行比较,而我则等于j(因此对自己)。并且因为当你找到匹配时你没有停止你的迭代,我的猜测是你的函数将总是返回输入数组的最后一个元素。