每个排序算法都是工作,但它是一个OVERKILL。
输入如下:
aa
cc
aa
bb
dd
bb
cc
我只需要:
aa
aa
cc
cc
bb
bb
dd
不需要每种模式的顺序。
这种工作有这样的算法吗?
答案 0 :(得分:6)
您只想在这里使用hashtable,或者更抽象地使用associative array。迭代输入,将其添加到哈希表中,如果尚未看到 1 的值(标记,如果您愿意),或者如果哈希表中已经存在,则将计数递增1
因此算法在时间和空间上都是 O(n),这是你可以合理预期的。我建议阅读一些哈希表,因为它是一种非常有用的数据结构,出现在算法和软件设计的各种各样的地方。
答案 1 :(得分:2)
好吧,从我的头顶开始你可以运行一个传递来计算每个元素存在多少,然后创建一个新的数组,并按顺序发布它们。那将是O(n)但不是“就地”。
因此:
// Make outputArrayCounter
// While inputArray has elements left:
// if current element is new, add to outputArrayCounter
// if current element has been seen before, increment a counter associated with that
// element.
// Part 2...
// Make outputArray
// create the appropriate number of elements as found in the outputArrayCounter for
// every different element type.
我们试试一个例子:
我们的原始输入为aa bb aa cc cc dd cc
。
我们将制作我们的计数器设备,并扫描输入。 aa
,第一个元素被读取,因为我们以前从未遇到过aa
,我们会将其添加到我们的计数器设备中。
计数器设备:[(aa, 1)]
现在让我们继续阅读下一个输入bb
。它也没有找到并添加:
计数器设备:[(aa, 1), (bb, 1)]
再次步骤并阅读aa
作为第三个元素。这可以在我们的设备中找到,因此我们不会再添加它,而是将与aa
相关联的计数器增加1。
计数器设备:[(aa, 2), (bb, 1)]
我会继续并给你终端计数器设备状态:
[(aa, 2), (bb, 1), (cc, 3), (dd, 1)]
现在我们浏览设备并多次打印出每个元素的数量,同时将 name 的每个元素放在一起。 (如果顺序很重要,这是一个实现细节,将确定是否使用关联的set-dictionary,或某种存储排序的双列数组设备。这是特定于语言的,但我相信你可以解决这个问题。如果你不能,在这里评论我会描述一个解决方案。)
print aa aa bb cc cc cc dd