在一次技术面试中,我被问到了这个问题。我知道用(在Java中)HashSet的方法来解决这个问题。
但是当面试官强调“给定数组中有非常大的数组,比如1000万个元素”这个词时,我不明白该怎么办。
我需要改变方法吗?如果不需要,如何高效地解决问题?
附注:算法或实现与语言无关。
谢谢。
在一次技术面试中,我被问到了这个问题。我知道用(在Java中)HashSet的方法来解决这个问题。
但是当面试官强调“给定数组中有非常大的数组,比如1000万个元素”这个词时,我不明白该怎么办。
我需要改变方法吗?如果不需要,如何高效地解决问题?
附注:算法或实现与语言无关。
谢谢。
我能装多少?
这个问题都只会被看作是积极的。 - riddle_me_this需要记住的一件事是,O表示法并不一定告诉你哪个算法是最快的。如果一个算法是O(n log n),另一个算法是O(n2),那么存在某个值M,使得第一个算法对于所有n > M都更快。但是,M可能比您需要处理的数据量要大得多。
我提出这个问题的原因是我认为HashSet可能仍然是最好的答案,尽管我必须对其进行分析才能确定。假设您不允许设置具有1000万个桶的哈希表,您仍然可以设置一个合理大小的表。例如,您可以创建一个大小为100,000的HashSet。然后,桶将成为对象集。如果n是数组的大小,则平均桶大小将为n / 100000。因此,要查看元素是否已经在HashSet中,并且如果没有,则需要添加它,将需要计算哈希值的固定时间,并且搜索存储在线性列表中的桶中的元素将需要O(n)的时间。从技术上讲,这意味着找到所有重复项的算法是O(n 2 )。但是,由于n 2 中的一个n是表示线性列表的,该列表比数组大小小得多(100000倍),因此我认为它仍然需要比O(n log n)排序快得多,对于1000万个项目。M的值,即O(n log n)排序变得更快的点,可能要大得多。(我只是猜测;要确定需要一些分析。)
我倾向于不使用排序,因为如果您所需做的只是查找重复项,则排序比您需要的工作要多。您不需要将元素按顺序排列,只需查找重复项即可。这对我来说表明排序可能不是最好的答案。
(*)请注意,在Java 8中,每个桶中的元素将是某种搜索树,可能是红黑树,而不是线性列表。因此,算法仍将是O(n log n),并且仍然可能比排序快得多。
function uniqueArray(arr){
var length = arr. length,
uniqueElementArray = [];
while(length >= 0){
obj [arr[length]] = true;
length-- ;
}
for(var i in obj){
uniqueElementArray.push[i];
}
return uniqueElementArray;
}
>>> arr = [3, 1, 3, 5, 4, 3, 4, 2, 1]
>>> for i, v in enumerate(arr):
>>> while arr[v] != arr[i]:
>>> arr[i], arr[v] = arr[v], arr[i]
>>> v = arr[i]
>>> arr
[3, 1, 2, 3, 4, 5, 4, 3, 1]
重复项出现在值不等于索引的位置。
>>> [v for i, v in enumerate(arr) if i != v]
[3, 4, 3, 1]
collections.Counter
而无需算法:from collections import Counter; c = Counter(<array>)
所有计数大于1的都是重复项。 - AChampion