找到JavaScript数组中唯一唯一值的最佳方法是什么

时间:2018-06-16 19:28:14

标签: javascript algorithm

在时间复杂度方面,在数组中找到唯一唯一值的最佳方式(效率)是多少。

示例:

  • findUniq([2, 1, 1, 1, 1, 1])应该返回2

  • findUniq([3, 4, 3, 3, 3, 3, 3, 3, 3])应该返回4

约束:

数组开头的值超过 2

数组只有数字。

数组只有一个唯一值,例如[1,7,1,1]或[4,2,2,2]

[3,4,5,3]不是有效输入。

我想知道我是否可以使用Set来解决这个问题。

这是带有for循环的解决方案,我不确定此解决方案是否会通过所有方案。

 let findUniq = (arr) => {
  for(let i = 0; i < arr.length; i++) {
    if (arr[i] !== arr[0]) {
      return arr[i]
    }
  }
}

6 个答案:

答案 0 :(得分:5)

您可以使用find方法并检查indexOf是否等于lastIndexOf。它将返回第一个匹配并停止循环。

const uniq = arr => arr.find((e, i) => arr.indexOf(e) == arr.lastIndexOf(e));

console.log(uniq([3, 4, 3, 3, 3, 3, 3, 3, 3]));
console.log(uniq([1, 2, 3, 1, 2]));
console.log(uniq([2, 1, 1, 1, 1, 1]));

答案 1 :(得分:2)

基于解决方案,其中元素#1等于数组中的元素#2。

一个班轮:const unique = arr => (arr[0] === arr[1]) ? arr.find((x) => x !== arr[0]) : (arr[0] === arr[2]) ? arr[1] : arr[0];

稍微更具可读性:

const unique = arr =>
  (arr[0] === arr[1])
    ? arr.find((x) => x !== arr[0])
    : (arr[0] === arr[2]) ? arr[1] : arr[0];


console.log(
  unique([2, 1, 2, 2]),
  unique([2, 3, 3]),
  unique([4, 4, 4, 3]),
  unique([4]) //Thanks Slai
);

<强>要求

  • 仅包含2个不同的数字。
  • 只有1个唯一值

更易读

const unique = arr => {
  if (arr[0] === arr[1])
    return arr.find((x) => x !== arr[0] );
  else 
    return (arr[0] === arr[2]) ? arr[1] : arr[0];
}

var arr = [2, 1, 2, 2],
    arr1 = [2, 3, 3],
    arr2 = [4, 4, 4, 3],
    arr3 = [4]; //Thanks Slai

console.log(unique(arr), unique(arr1), unique(arr2), unique(arr3));

效率更高?

function unique(arr) {
  if (arr[0] === arr[1]) {
    for (let i = 2, x = arr.length; i < x; i++) // Using 2 because  0 & 1 are dups
      if (arr[i] !== arr[0]) return arr[i];
  } else {
    return (arr[0] === arr[2]) ? arr[1] : arr[0];
  }  
}

var arr = [2, 1, 2, 2],
    arr1 = [2, 3, 3],
    arr2 = [4, 4, 4, 3],
    arr3 = [4]; //Thanks Sali

console.log(unique(arr), unique(arr1), unique(arr2), unique(arr3));

答案 2 :(得分:1)

使用此方法

var unique = function(xs) {
  return xs.filter(function(x, i) {
    return xs.indexOf(x) === i
  })
}

此代码重新调整所有元素而不重复 使用两个循环来比较数组的每个元素与其他元素如果有另一个元素中断循环,否则最后重新调整它

function unique(arr) {
  for(var i=0;i<arr.length;i++) {
    for (var j=i; j<arr.length; j++)
    if(arr[i] != arr[j]) continue
    if (j== arr.length) return i
    break
  }

答案 3 :(得分:0)

你可以简单地创建一个计数图,然后迭代你的地图,找到计数为1的元素。

时间复杂度:O(n)

&#13;
&#13;
var arr = [3, 4, 3, 3, 3, 3, 3, 3, 3];
var map = arr.reduce((a,val)=>{
  a[val] = (a[val]? a[val]+1 :1) ;
  return a;
},{});
var result;
Object.keys(map).forEach((key)=>{
  if(map[key] === 1)
    result = key;
});
console.log(result);
&#13;
&#13;
&#13;

如果数组中的每个重复元素重复次数甚至超过您只需使用Xor运算符:

&#13;
&#13;
var findUnique = (arr)=> arr.reduce((a,val)=> a^val,0);

console.log(findUnique([3, 4, 3, 3, 3, 3, 3, 3, 3,5,5,3,3]));
console.log(findUnique([2,1,2,2,2,3,3,4,4]));
&#13;
&#13;
&#13;

答案 4 :(得分:0)

虽然我非常喜欢这个问题的.reduce.filter.findSet方法,但我认为它可以更轻松地解决 - 我不太确定考虑到不同的场景,这将如何转化为实际成本,我可以说,如果循环遇到已知值,它会跳过进一步的处理,并且对于每个新值,它会检查在找到的位置后面是否还有另一个相同的值。

Object.defineProperty(Array.prototype, 'uniqueValue', {
  enumerable: false,
  configurable: false,
  get: function() {
    let found = [];
    for(let n of this) {
      if(n in found) continue;
      if(this.indexOf(n, this.indexOf(n)+1) === -1) return n;
      found.push(n);
    }
  }
});

console.log([2, 1, 1, 1, 1, 1].uniqueValue)
console.log([3, 4, 3, 3, 3, 3, 3, 3, 3].uniqueValue)
console.log([3, 4, 3, 3, 3, 4, 3, 3, 3, 5, 5, 7, 7, 8, 8, 9].uniqueValue)

答案 5 :(得分:-1)

我可以想出一些方法来实现这个目标:

  1. 使用Set
  2. &#13;
    &#13;
    const arr = [2,1,1,1,1];
    
    const value = new Set(arr).values().next();
    
    console.log(value.value);
    &#13;
    &#13;
    &#13;

    1. 使用find
    2. &#13;
      &#13;
      const arr = [3, 4, 3, 3, 3, 3];
      
      const value = arr.find(value => arr.filter(x => x === value).length === 1);
      
      console.log(value);
      &#13;
      &#13;
      &#13;

      1. 使用reduce
      2. &#13;
        &#13;
        const arr = [1, 2, 2, 2, 3, 3, 3, 4, 4, 4];
        
        const value = arr.reduce((current, val) => current === val ? 0 : current);
        
        console.log(value);
        &#13;
        &#13;
        &#13;