场景描述
假设我们有多个数组,每个数组存放的是图片的 URL,但存在很多重复项。我们需要得到一个对所有数组去重的结果数组。
思路1: 把所有数组组合起来,通过 Set
去重
实现代码
function deduplicateImages(...arrays) {
// 将所有数组扁平化并组合成一个数组
const combined = [].concat(...arrays);
// 使用 Set 去重
const uniqueSet = new Set(combined);
// 将 Set 转换回数组
return Array.from(uniqueSet);
}
优点
- 简单易懂:代码逻辑直观,容易理解。
- 性能较好:对于大多数情况,尤其是中小型数据集,这种方法的性能是可接受的。
- 利用
Set
的高效性:Set
的查找和插入操作平均时间复杂度为 O(1),使得去重操作非常高效。
缺点
- 空间开销:
- 需要额外的空间来存储扁平化后的数组和
Set
,对于非常大的数据集,可能会消耗较多内存。 - 如果每个数组都很大,组合后的数组可能会非常庞大,导致内存不足的问题。
- 需要额外的空间来存储扁平化后的数组和
- 无法保证顺序:
Set
不保留插入顺序,因此最终返回的数组中的元素顺序可能与原始数组中的顺序不同。
思路2: 对其中一个数组的所有元素进行遍历,在遍历中判断其他数组是否都包含这个元素
实现代码
function deduplicateImages(...arrays) {
const firstArray = arrays[0];
const otherArrays = arrays.slice(1);
const result = [];
for (const item of firstArray) {
if (otherArrays.every(arr => arr.includes(item))) {
result.push(item);
}
}
return result;
}
优点
- 空间开销较小:不需要将所有数组组合成一个大数组,减少了内存开销。
- 保持顺序:可以保持第一个数组中的元素顺序。
缺点
- 性能较差:
- 每次检查一个元素是否存在于其他数组中时,都需要遍历其他数组,时间复杂度较高,为 O(n * m),其中 n 是第一个数组的长度,m 是其他数组的总长度。
- 对于大型数据集,这种方法的性能较差,可能会导致性能瓶颈。
优化思路2
为了提高性能,我们可以使用 Set
来优化查找操作,减少每次查找的时间复杂度。
优化后的实现代码
function intersect(...arr){
const sets = arr.map(item => new Set(item))
const result = sets[0]
for(let i = 1; i < sets.length; i++){
result.forEach(item => {
if(!sets[i].has(item)){
result.delete(item)
}
})
}
return Array.from(result)
}
const array1 = [1, 2, 3, 4, 5];
const array2 = [4, 5, 6, 7, 8];
const array3 = [5, 6, 7, 8, 9];
console.log(intersect(array1, array2, array3))
优化后的优点
- 性能提升:
- 使用
Set
进行查找操作,时间复杂度为 O(1),大大提高了查找效率。 - 整体时间复杂度降低为 O(n * m),其中 n 是第一个数组的长度,m 是其他数组的数量。
- 使用