【问题标题】:Popping elements from array efficiently有效地从数组中弹出元素
【发布时间】:2020-05-31 02:46:09
【问题描述】:

考虑一个我们知道从 0 开始依次包含从 0 到 n 的整数的数组。例如:

a=[0,1,2]

现在,我们弹出位置 1 的元素。

a.pop(1)

我们剩下的数组:

[0,2]

我们有 a[0]=0,a[1]=2。 让我们弹出位置 0 的元素。

a.pop(0)

我们只剩下:

[2]

现在,引用 a[0] 将产生 2。

这是我想要的行为,除了弹出操作的时间为 O(n),因为需要将整个数组复制到左侧。有没有办法更有效地做到这一点,以便每个弹出(或等效)操作不超过 O(log(n))?如果需要,可以占用另一个 O(n) 空间。

在上面显示的操作序列之后,最后查询索引 0 应该仍然返回 2。我尝试将弹出的元素存储在二叉搜索树中(实际上没有弹出),但逻辑变得太复杂了。

【问题讨论】:

  • 这是一个列表而不是一个数组。您可以使用collections.deque,它在两端提供高效的弹出/插入
  • 也在中间?阵列可能非常大,并且大多数爆裂声可能发生在中心。
  • 不,不在中间。我读了pop(0) 两次。我的错误
  • list 基于array,它为您提供O(1) 访问时间,而如果您想弹出元素,则需要O(n) 时间来弹出元素。如果你有一棵树,比方说 RB-tree,它可以用O(log(n)) 时间弹出一个元素,但你也需要O(log(n)) 时间来访问一个元素。所以这里是权衡。如果要O(1)的访问时间,相信不可能有O(log(n))的弹出时间。
  • @Sraw "list is based on array" 与“Python 基于计算机”差不多。如果你想让它被认真对待,你必须更具体地说明该声明的含义。

标签: python arrays algorithm


【解决方案1】:

您似乎在要求另一种数据结构。链表擅长从任意位置插入和删除,但需要对要插入或删除的位置有一个引用;否则,您将花费 O(n) 扫描到要插入或删除的位置。

据我所知,Python 的标准库中没有链表,但你可以自己实现。

归根结底,您无法在更短的时间内完成“完全相同的事情”;必须付出一些东西。您需要放宽您的一项要求(例如,使用列表类型)。

您可能可以放宽的另一个要求是“现有元素需要保持相同的顺序”。如果您不介意重新排序,可以将 lst[i] 与 lst[-1] 交换。然后,从末尾弹出(这对列表很有效)。这可以很容易地使用 Python 的元组赋值来完成。像这样:

lst[i], lst[-1] = lst[-1], lst[i]  # swap
lst.pop()  # Now, the item that you wanted removed is gone,
           # but the remaining elements are not
           # all in the same order as before,
           # but they mostly are.

这通常是一个可行的选择,因为您并不总是关心列表的顺序。

【讨论】:

  • 谢谢。在这个应用程序中,顺序很重要。我希望使用额外的 O(n) 空间将是“给予”的东西。此外,输入始终为 0,1,2,..n。我希望这也能成为我们的优势。
  • re 0, 1, 2, ... n: 嗯。一旦你弹出一个元素,你就不再具有连续数字的属性。
  • 是的,但我们总是从连续的数字开始,而不是任何可能的数组。这些信息不能为我们所用?
  • 我明白了。那你应该把它放在你的问题中。是的,我认为可以利用这一事实:与其维护尚未弹出的列表,不如保留已弹出的有序树(例如自平衡二叉树)。然后,当您想要迭代剩下的内容时,您可以“并行”迭代 range(n+1) 与树的元素,然后您可以使用它来过滤掉 range(n+1) 中的元素树。
  • 我认为第一行表明了这一点。刚刚对其进行了编辑以进一步澄清这一点。我对二叉树有同样的想法并试图在这里实现它:github.com/ryu577/algorithms/blob/master/algorith/sequencegen/…" 但遇到了一些复杂性,二叉树不再明显有帮助。也许我做错了,所以希望得到这种方法的一些细节是由更新鲜和更好的头脑得出的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
  • 2017-08-12
  • 1970-01-01
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多