【问题标题】:Binary search on a linked list of nodes using a HashMap in O(logN) Time Complexity在 O(logN) 时间复杂度中使用 HashMap 对节点链表进行二分搜索
【发布时间】:2016-11-15 20:03:17
【问题描述】:

你能以 O(logN) 的时间复杂度对节点(对象)的排序链表进行二分搜索吗?我知道 Linked Lists 不支持直接索引,所以你不能做类似 list[3] 或 list.get(3) 的事情,所以基本上你需要遍历列表的所有元素来找到索引中间元素。但是如果你有一个额外的数据结构,比如 HashMap(key = index,value = node) 呢?这行得通吗?

示例: 假设我们有一个列表:

1 -> 4 -> 7 -> 9 -> 14 -> 18

还有用来获取节点的HashMap O(1):

0 -> 1
1 -> 4
2 -> 7
3 -> 9
4 -> 14
5 -> 18

现在,如果我们想找到 14 个,我们会这样做:

binarySearch(0,5) : middle = 2 -> get node 7 from the Hashmap. 14 > 7 so ->
binarySearch(3,5) : middle = 4 -> get node 14 from the Hashmap. 14 == 14 ->Voila

当然,要构建这个 hashmap,你必须做 N 次操作,所以时间复杂度为 O(N),但是如果你已经有了 HashMap,这可以工作吗?

如果是,您不能使用这种方法在具有附加 HashMap 的链表上以 O(nlogn) 时间复杂度进行插入排序吗?

基本上:

 1. for each element ( O(n) )
    2. find the position of the element in the list in O(logN) with binary search that uses the Hashmap to get the element at the middle position in O(1).
    3. insert the element in the Linked List in O(1)
    4. insert the (index,element) into the Hashmap in O(1)

O(nlogn) 时间复杂度。还是我在做/假设有什么问题?

【问题讨论】:

  • 是的,这样的事情会奏效。您甚至可以使用数组而不是散列映射作为间接索引。您只需在启动时以及添加或删除节点时构建一次索引。如果列表不经常更改,那么这是一个不错的选择。
  • 是的,我后来意识到第一个问题(在链表上使用 (O(logN) 时间复杂度的二进制搜索)是愚蠢的,因为我实际上是在对数组进行二进制搜索,而不是在链表上。而且插入排序也不起作用,因为当我在 hashmap 中插入新对时,我还需要更新 hashmap 中的其他键(索引),这将需要 O(N) 时间复杂度...
  • @EmanYalpsid:听起来你应该write an answer to your own question。 :-)

标签: algorithm sorting data-structures hashmap binary-search


【解决方案1】:

这个想法非常好,下面是如何让它发挥作用:作为键,你可以使用节点的值。如果列表节点值是唯一的,那么您可以使用节点作为哈希映射的值(否则为节点列表)。所以你仍然可以像往常一样在列表中从一个节点到另一个节点,但你也可以在 O(1) 中按值访问。

如果值发生变化,则必须在插入和删除时更新哈希映射,但一切都是 O(1) 或 O(c),其中 c 是列表中重复值的最大数量,如果 c 没有t 依赖于 n,那么即使有重复也是 O(1),否则 O(n)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-28
    • 2021-09-24
    • 2021-03-29
    • 1970-01-01
    • 2020-01-29
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多