【问题标题】:linked list, implement peekAt(k) method in log(k)链表,在log(k)中实现peekAt(k)方法
【发布时间】:2020-08-28 00:52:49
【问题描述】:

我被要求设计一个数据结构,它的作用就像一个堆栈,大小不受限制,它将支持以下方法,并具有给定的运行时限制。

push(s) - 将 s 推入数据结构 - O(1) pop() - 移除并返回最后插入的元素 O(1) middle() - 按插入顺序返回索引为 n/2 的元素(不删除),其中 n 是数据结构中元素的当前数量。 - O(1) peekAt(k) - 按插入顺序返回第k个元素(栈底为k=1) - O(log(k))

这 3 种方法将使用链表,但我应该如何实现 peekAt(k) 方法。

谢谢。

【问题讨论】:

标签: data-structures linked-list time-complexity


【解决方案1】:

您要查找的是Skip List 的变体,它按插入顺序排序。

为了支持O(logk) 而不是O(logn),您真正需要的唯一修改是在开始搜索之前从下往上进行,例如:

// Assume head points to the first element in the lower tier list.
current = head
while (current->next->index < k) current = current->up

此时,您要查找的元素介于 currentcurrent-&gt;next 之间。您可以使用常规跳过列表搜索值 k 来查找它,从 current 开始而不是顶层。

请注意,查找current 是在O(logk) 中完成的,因为您基本上是反复检查:

1 < k ?
2 < k ?
4 < k ?
8 < k ?
...
2^ceil(logk) < k ?

也就是说,O(log(k)) 检查。

【讨论】:

  • 好的,谢谢。但是我如何保持其他方法的 O(1) 时间复杂度?
  • @שליולוי:由于您只将元素添加到顶部(跳过列表的最后一个元素),因此您以1/2^tier 的概率将其连接到每一层中的前一个元素。这意味着,底层:2^0=1,然后是 1/2、1/4、1/8 等等。这意味着,每次插入都花费1+1/2+1/4+... &lt; 2,这是恒定的。删除类似。中位数保持不变。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-27
  • 1970-01-01
  • 2013-07-24
  • 2020-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多