有一次,当我接受采访时,我被问到这个问题,我认为面试官有误。
以下是问题:
考虑我们有一个具有运算符<的数据类型。我们有两个选择。
在std :: set中添加所有这些数据,然后使用std :: find和std :: insert查询和添加元素。在这种情况下,前N个元素的插入是N * logN,每个查询和插入都是logN。
第二个是在std :: list中插入所有这些值,然后对它进行排序,并在查询和插入后使用std :: binary_search和insert。这里插入如果N +排序N * logN(根据访调员)和每个binary_search并插入logN。
我已经回答说第一种情况更快,但是面试官告诉我,由于std :: set是通过红黑树实现的,因此重新平衡是一项昂贵的操作,因此std :: list的情况更快。但是我注意到std :: list的排序不能是N * logN,因为它没有随机访问迭代器。
请帮助我最后了解哪种情况更好,为什么?
答案 0 :(得分:3)
可以使用O(n*log(n))
在merge sort
中对列表进行排序。然而,存在一个更大的问题 - 由于缺乏随机访问,二进制搜索无法精确地应用于列表。
请注意,列表可以通过多种不同方式实现,包括使用数组作为后备,在这种情况下,您也可以进行随机访问(但std::list
不是这种情况)。
问题的最佳解决方案是使用std::vector
并对其执行二进制搜索(在对其进行排序后)。这样你知道有随机访问操作符。
编辑:由于您的容器中的值似乎可以交互式更改,因此预选排序然后执行二进制搜索不是一种选择。之所以如此,是因为在插入新值之后,您将不得不再次对元素进行排序。更复杂的列表版本,如跳过列表支持,但否则设置应该更快。
答案 1 :(得分:0)
是的面试官是错的。
是的,你应该继续面试,直到找到一家更好的公司: - )