【问题标题】:How to find amortized complexity for insertion & deletion of element in stack of stacks?如何找到在堆栈堆栈中插入和删除元素的摊销复杂度?
【发布时间】:2015-02-10 09:55:20
【问题描述】:

最近去面试,面试官问了我这个问题。

有 k+1 堆大小1, 2^1, 2^2, 2^3, ...,2^k。让我们分别称他们为stack 1, stack 2, ... stack k+1。当insert(x) 被调用时,元素被插入到第一个堆栈,即大小为 1 的堆栈。如果该堆栈已满,则该堆栈的元素被移动到下一个堆栈,然后元素被插入第一个堆栈。它类似于管道操作。堆栈 1 将元素推入堆栈 2,堆栈 2 推入堆栈 3,依此类推。如果所有堆栈都已满,那么我们会抛出一个错误,说明堆栈溢出。还有另一个操作,delete(x)。它从堆栈堆栈中删除 x。因此,如果 x 不是最顶部的元素,即它不存在于堆栈 1 中,则我们从中弹出元素,然后移动元素,然后再次尝试弹出,直到找到该元素并将其删除。此实现的插入和删除的摊销复杂度是多少?

编辑 1:展示插入和删除的工作原理。
假设有 2 个堆栈,堆栈 1 和堆栈 2 的大小分别为 2^0 和 2^1。
迭代 0:堆栈 1 -> {},堆栈 2 -> {}迭代 1:插入 (1)。堆栈 1 -> {1},堆栈 2 -> {},顶部 -> 1
迭代 2:插入 (2)。堆栈 1 -> {2},堆栈 2 -> {1},顶部 -> 2
迭代 3:插入 (3)。堆栈 1 -> {3},堆栈 2 -> {2,1},顶部 -> 3
迭代 4:插入 (4)。溢出异常。堆栈 1 -> {3},堆栈 2 -> {2,1},顶部 -> 3
迭代 5:删除 (2)。

  • 我们弹出 3,因为 2!=3 并继续。堆栈 1 -> {2},堆栈 2 -> {1},顶部 -> 2
  • 我们弹出 2 并返回。堆栈 1 -> {1},堆栈 2 -> {},顶部 -> 1
    迭代 6:插入 (4)。堆栈 1 -> {4},堆栈 2 -> {1},顶部 -> 3
    希望这两个操作现在都清楚了:)

我尽了最大努力,只能说出最坏情况的时间复杂度,即1+2^1+2^2+..+2^k(几何级数总和)。我不是在寻找最坏情况的时间复杂度。我什至无法达到摊销的复杂性。谁能帮助理解如何计算这个问题的摊销复杂度?

【问题讨论】:

  • 如果您不立即知道1+2^1+2^2+..+2^k 的总和是什么,您可能需要进一步研究。无论如何,尚不清楚当堆栈已满时元素如何移动。您是将它们全部移到下一个堆栈上,还是只移动一个?
  • 考虑:在你插入一个导致你转储堆栈n的元素之后,它下面的所有堆栈必须是什么样子?你多久转储一次堆栈n?因此,分配给堆栈n 的每次插入摊销成本是多少?
  • @n.m.我知道如何解决几何和!请正确阅读问题。我要求的是渐近复杂度,但不是最差的时间复杂度!!该总和导致最坏情况的时间复杂度。无论如何,我们将所有元素一个接一个地移动(类似于在给定索引中插入数组中的元素会导致所有元素移动)。
  • @Sneftel 转储堆栈 n 是什么意思?我们不会删除任何堆栈,如果所有堆栈都已满,那么我们会抛出错误消息。编辑问题以显示插入将如何进行。
  • 啊,好的。我懂了。因此,当您在 (k+1) 个堆栈中插入 N=((2^k+1)-1) 个元素时,1 个元素根本没有移动,2 个元素移动了 1 个位置,4 个元素移动了 2 个位置, ...,并且 2^k 个元素移动了 k 个位置。因此,您需要找到总和 0*1 + 1*2 + 2*4 + 3*8 + ... k*2^k,然后将其除以 (2^(k+1)-1) 以获得每个元素的操作数。这小于 k,但大于 k/2(实际上它几乎正好是 k-1),因此渐近摊销复杂度为 O(log N)。

标签: algorithm time-complexity amortized-analysis


【解决方案1】:

摊销分析最常用的工具是“潜在方法”,您可以查阅维基百科。

不过,我不擅长编程。让我们来谈谈宗教。让我们谈谈地狱吧。

地狱由k 同心圆环组成,护城河将圆环隔开。从一层到下一层穿过护城河的唯一方法是雇佣摆渡人……但摆渡人会想要一枚金币作为回报。当然,在地狱中没有办法获得黄金;不管你用什么埋葬,这就是你可以花费的。(进入地狱的第一环也需要一枚硬币,顺便说一句。)

有趣的是,地狱戒指的规则与你的堆叠规则相同。每个环比之前的大一倍(尽量不要考虑它的几何形状),每当一个环满了并且有人想搬进去时,首先那个环中的人必须雇用摆渡人来接他们到下一个环。

奇怪的是,整个地狱只有一个摆渡人,而他的船也只能坐一个;他神奇地出现在他被雇用的任何护城河中,并花一分钟运送雇用他的人。所以一次只能运送一个人。

这意味着在整个地狱中每分钟只花费一枚金币。这意味着,如果一个新人想进入地狱,而前几个环都已满,摆渡人需要几分钟才能将他带入地狱。

地狱现在是空的,但是在电影中说话的 1023 人刚刚死去,所以它即将被 1023 人填满。他们将用 1、2、4、8、16、32、64、128、256 和 512 人填充前 9 个圈子。

  1. 最终进入 512 环的每个人应该用多少硬币埋葬?那么每个最终将进入 256 环的人呢?
  2. 集体葬礼总共应该使用多少枚硬币?
  3. 摆渡人需要多长时间才能完成将所有人运送到位?
  4. 平均每个人要等多久才能进入地狱?
  5. insert 的摊销复杂度是多少?

【讨论】:

  • 很好的插图 :) 但是有一个问题,人不是随机选择的(第 4 段最后一行)。最后一个人被选择去下一个环。顺便说一句,我理解@n.m. 对摊销复杂性的解释并且看起来是正确的:)
  • @Abhishek 这实际上对分析无关紧要,但我已经把它拿出来了。
猜你喜欢
  • 2021-06-21
  • 1970-01-01
  • 2021-06-02
  • 1970-01-01
  • 2017-05-18
  • 2014-11-09
  • 1970-01-01
  • 1970-01-01
  • 2013-11-07
相关资源
最近更新 更多