一尘不染

数组可以比排序更有效地分组吗?

algorithm

在处理算法问题的示例代码时,我遇到了对输入数组进行排序的情况,尽管我只需要将相同的元素分组在一起,而不必按任何特定的顺序进行分组,例如:

{1,2,4,1,4,3,2}→{1,1,2,2,4,4,3}或{1,1,2,2,3,4,4}或{3 ,1,1,2,2,4,4}或…

令我感到奇怪的 与对数组进行排序相比,是否有可能将数组中的相同元素更有效地组合在一起?

一方面,不需要将元素移动到特定位置这一事实意味着找到需要较少交换的订单的更多自由。另一方面,跟踪组中每个元素的位置以及最佳的最终位置是什么,而不是简单地对数组进行排序,可能需要更多的计算。

逻辑候选将是一种 计数排序 ,但是如果数组长度和/或值范围不切实际地大怎么办?

为了便于讨论,我们假设数组很大(例如一百万个元素),包含32位整数,每个值中相同元素的数量可以是1到一百万。


更新:对于支持字典的语言,萨尔瓦多·达利(Salvador
Dali)的答案显然是要走的路。我仍然会对听到老式的比较和交换方法,或者如果有的话使用较少空间的方法感兴趣。


阅读 185

收藏
2020-07-28

共1个答案

一尘不染

是的,您要做的就是创建字典并计算每次都有多少个元素。之后,只需遍历该字典中的键并输出与该键的值相同次数的键即可。

快速的python实现:

from collections import Counter
arr = [1,2,4,1,4,3,2]
cnt, grouped = Counter(arr), []  # counter create a dictionary which counts the number of each element
for k, v in cnt.iteritems():
    grouped += [k] * v # [k] * v create an array of length v, which has all elements equal to k

print grouped

这将O(n)使用潜在的O(n)额外空间将所有元素及时分组。这比在O(n logn)时间上可以实现并可以就地完成的排序更为有效(就时间复杂度而言)。

2020-07-28