给定一个元素列表,哪些是通过某个键对元素进行分组的最有效方法?
例如,如果输入为/* "Octile" heuristic */
int h(node n)
{
int dx = abs(n.x - goal.x);
int dy = abs(n.y - goal.y);
if (dx > dy)
return 14 * dy + 10 * (dx - dy);
else
return 14 * dx + 10 * (dy - dx);
}
,则有效输出可以是{a,c,a,b,c,b,b}
或{a,a,b,b,b,c,c}
。
显然,如果密钥的类型遵守订单,则可以使用排序算法,这会给我们带来{b,b,b,c,c,a,a}
的复杂性。
但是,密钥可能只是相等而不是订单。例如,O(nlogn)
但询问typeof(dog) != typeof(cat)
是否有意义。
当然,可以强制排序(例如typeof(dog) < typeof(cat)
并使用词法顺序),但由于不需要严格的顺序(仅限分组),我想知道是否有比排序更有效的方法。
答案 0 :(得分:1)
我会使用未排序的链表和哈希映射来插入点,就像这样(伪代码):
function group_sort(unsorted_list)
node_map = new hash_map
sorted_list = new linked_list
foreach node in unsorted_list
last_node = node_map.get(type_of(node))
if last_node found
sorted_list.insert_after(last_node,node)
else
sorted_list.append(node)
node_map.add(type_of(node),node)
delete node_map
return sorted_list
哈希映射查找和插入主要是O(1),哈希映射插入甚至可能很少,具体取决于您的数据。链接列表插入始终为O(1)。这使得函数几乎为O(n),而且肯定是O(nlogn)。
答案 1 :(得分:-1)
您可以将每个项目插入multiset