假设我们有一个长度为N的对象数组(所有对象都有相同的字段集)。
我们有一个长度为N的数组,它们代表某个对象的字段(例如代表ID的数字数组)。
现在我们要按字段对对象数组进行排序,该字段在第二个数组中表示,顺序与第二个数组相同。
例如,这里有2个数组(如说明中所示)和预期结果:
A = [ {id: 1, color: "red"}, {id: 2, color: "green"}, {id: 3, color: "blue"} ]
B = [ "green", "blue", "red"]
sortByColorByExample(A, B) ==
[ {id: 2, color: "green"}, {id: 3, color: "blue"}, {id: 1, color: "red"} ]
如何有效实施'按示例排序'功能?我无法想出比O(N^2)
更好的东西。
答案 0 :(得分:3)
这假设您有B
中的元素与A
从M
的元素构建地图(比如说B
)到他们的位置(O(N)
)
对于A
(O(N)
)的每个元素,访问地图以查找将其放置在已排序数组中的位置(O(log(N))
并有效实现地图)
总复杂度:O(NlogN)
时间和O(N)
空间
答案 1 :(得分:2)
假设我们正在对项目的颜色进行排序。然后创建一个字典 d ,将每种颜色映射到A中具有该颜色的项目列表。然后迭代列表B中的颜色,并为每个颜色 c 输出(并删除)列表 d [ c ]中的值。这在O( n )时间运行,其中O( n )是字典的额外空间。
请注意,如果根据B中的示例无法对A进行排序,您必须决定该怎么做:您是否引发错误?选择最大化匹配数量的顺序?或者是什么?
无论如何,这是Python的快速实现:
from collections import defaultdict
def sorted_by_example(A, B, key):
"""Return a list consisting of the elements from the sequence A in the
order given by the sequence B. The function key takes an element
of A and returns the value that is used to match elements from B.
If A cannot be sorted by example, raise IndexError.
"""
d = defaultdict(list)
for a in A:
d[key(a)].append(a)
return [d[b].pop() for b in B]
>>> A = [{'id': 1, 'color': 'red'}, {'id': 2, 'color': 'green'}, {'id': 3, 'color': 'blue'}]
>>> B = ['green', 'blue', 'red']
>>> from operator import itemgetter
>>> sorted_by_example(A, B, itemgetter('color'))
[{'color': 'green', 'id': 2}, {'color': 'blue', 'id': 3}, {'color': 'red', 'id': 1}]
请注意,此方法处理序列B中存在多个相同值的情况,例如:
>>> A = 'proper copper coffee pot'.split()
>>> B = 'ccpp'
>>> ' '.join(sorted_by_example(A, B, itemgetter(0)))
'coffee copper pot proper'
当B
中有多个相同的值时,我们会以相反的顺序获取A
中的相应元素,但这只是实现的假象:使用collections.deque
如果首选,我们可以安排以原始顺序获取popleft
的相应元素,而不是列表(而pop
而不是A
)。
答案 2 :(得分:0)
创建一个数组数组,将其称为大小为B.length的C. 循环A.如果颜色为“绿色”则将其放在C [0]中。如果它的颜色为“蓝色”,则将其放在C [1]中,如果它的颜色为红色则将其放在C [2]中。 当你完成后,通过C,并将其展平为原始结构。
答案 3 :(得分:0)
合并排序不会更好吗?创建B.length数组,一个用于B中的每个元素,然后通过A,并将它们放在适当的较小数组中,然后在完成所有操作时将数组合并在一起。它应该在O(2n)附近
答案 4 :(得分:0)
HashMap
个此类字段而不是List
个对象。 O(n) [假设这些关键字段存在重复值] 例如。 key = green将包含字段值为Green
的所有对象总运行时间为O(n),但就地图和辅助阵列而言需要一些额外的内存
最后,您将根据您的要求对数组进行排序。