在时间复杂度方面,在数组中找到唯一唯一值的最佳方式(效率)是多少。
示例:
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]
}
}
}
答案 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
);
<强>要求强>:
更易读
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)
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;
如果数组中的每个重复元素重复次数甚至超过您只需使用Xor
运算符:
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;
答案 4 :(得分:0)
虽然我非常喜欢这个问题的.reduce
,.filter
,.find
和Set
方法,但我认为它可以更轻松地解决 - 我不太确定考虑到不同的场景,这将如何转化为实际成本,我可以说,如果循环遇到已知值,它会跳过进一步的处理,并且对于每个新值,它会检查在找到的位置后面是否还有另一个相同的值。
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)
我可以想出一些方法来实现这个目标:
Set
const arr = [2,1,1,1,1];
const value = new Set(arr).values().next();
console.log(value.value);
&#13;
find
const arr = [3, 4, 3, 3, 3, 3];
const value = arr.find(value => arr.filter(x => x === value).length === 1);
console.log(value);
&#13;
reduce
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;