Это наиболее эффективный способ, который я могу представить, поскольку он не включает Array.indexOf()
или Array.lastIndexOf()
, которые имеют сложность O (n), и использование внутри любого цикла сложности O (n) сделает полную сложность O (n) ^ 2).
Мой первый цикл имеет сложность O (n / 2) или O ((n / 2) + 1), так как сложность поиска в хэше равна O (1). Наихудшая сложность второго цикла, когда в массиве нет дубликатов, равна O (n), а наилучшая сложность, когда дубликат каждого элемента - O (n / 2).
function duplicates(arr) {
let duplicates = [],
d = {},
i = 0,
j = arr.length - 1;
// Complexity O(n/2)
while (i <= j) {
if (i === j)
d[arr[i]] ? d[arr[i]] += 1 : d[arr[i]] = 1; // Complexity O(1)
else {
d[arr[i]] ? d[arr[i]] += 1 : d[arr[i]] = 1; // Complexity O(1)
d[arr[j]] ? d[arr[j]] += 1 : d[arr[j]] = 1; // Complexity O(1)
}
++i;
--j;
}
// Worst complexity O(n), best complexity O(n/2)
for (let k in d) {
if (d[k] > 1)
duplicates.push(k);
}
return duplicates;
}
console.log(duplicates([5,6,4,9,2,3,5,3,4,1,5,4,9]));
console.log(duplicates([2,3,4,5,4,3,4]));
console.log(duplicates([4,5,2,9]));
console.log(duplicates([4,5,2,9,2,5,9,4]));