【问题标题】:Big Oh worst case analysis - if statement inside loopBig Oh 最坏情况分析 - 循环内的 if 语句
【发布时间】:2022-09-23 04:56:53
【问题描述】:

对于下面代码的最坏情况分析,我认为它是 O(n^2),但是我的教授声明它的 O(n),认为每个元素的最大操作量是 2(一次推送和一次弹出) )。

  • 既然是if-statement,不就是一个吗? push 和 pop 的表现如何?
  • 如果这是“最坏情况”,为什么我们不能争辩首先推送 n-1 个元素,然后在最后一次迭代中遍历整个堆栈,从而导致 O(n^2)?
void foo (int n){
    Stack<int> stack = new Stack();

    i = 0;

    while (i < n) {
        int key = random int from 1 to n
        
        if (key is odd) 
            stack.push(key);
        else {
            j = 0;

            while (j < key and !stack.isEmpty()){
                stack.pop();

            j = j + 1;
        }

        i = i + 1;
    }
}

  • 如果你在数苹果,你知道你可以拿走它们,将它们重新组织成组,然后数组。您可以以任何方便的方式重新排列它们。你的教授只是用工作而不是苹果来做这件事。他可以重新排列已完成的工作单元并进行统计。他只是按照完成的元素对工作进行分组。
  • 你是两个都完全正确。最坏的情况它最多取O(n),有n个步骤,所以这是O(n^2)。然而,这已经摊销O(1) 表示 n - 1,所以也是O(n - 1 + n) = O(2n-1) = O(n);这是一个更严格的界限。
  • @Neil:你是对的,但是OP关于最后一次迭代的论点是错误的,因为只有最后一次......

标签: algorithm if-statement time-complexity big-o complexity-theory


【解决方案1】:

这里最好的情况是每个绘制的随机值都是偶数。在这种情况下,循环的每次迭代都只是无操作。没有项目将被推入堆栈或从堆栈中弹出。在最坏的情况下,每个抽取的随机值都是奇数。在这种情况下,每个项目都将被推入堆栈。

在最好和最坏的情况下,循环的运行时间都是O(n)。然而,在最坏的情况下,循环还需要O(n) 的堆栈存储空间。

请注意,在最坏情况下绘制许多赔率然后绘制偶数不会改变循环复杂度,它仍然是O(n)

【讨论】:

  • 最坏的情况可以协商。您还可以获得 n-1 次推送和 n-1 次弹出,而不仅仅是 n 次推送。 (当然在渐近意义上没有区别。)
  • @YvesDaoust 是的,它可能会引入 2 倍,但不会改变运行时间或空间复杂度。
  • 你的意思是渐近的复杂。它确实改变了普通的复杂性和运行时间。
  • 我认为@YvesDaoust 的意思是,尽管对于大 O 表示法系数并不重要,但对于步数来说(就运行时间而言)最坏的情况是 n 赔率并不完全正确,因为它只导致 n推,而 n-1 赔率加 1 偶数导致 n-1 推和 n-1 弹出。
【解决方案2】:

这是一个棘手的问题!你的教授正在用与你不同的范式来解决这个问题(这有时很有帮助)。与其根据循环将做什么来考虑这个问题,不如根据每个元素被“触摸”多少次来考虑这个问题。

对于这个问题,你要“触摸”n程序执行期间的整数——这些是您正在操作的“元素”。对于每个元素,想想你的程序可以用它做什么。你怎么看?

你可以那个元素到你的堆栈上,或者你可以流行音乐关了吧?

接下来,考虑这个问题:是否可以推送一个元素(整数)已经入栈回到堆栈上?

答案是不。一旦一个整数被压入堆栈,while 循环将永远不会返回该整数。变量一世总是递增但从不递减。

因此,对于每个元素,其中有n, 你可以最多将其压入堆栈一次,最多弹出一次。渐近地,这可以解决上)复杂。

将来,当你在解决像这样一个棘手的问题时,试着看看改变你的范式是否有助于解决这个问题。 :)

【讨论】:

    【解决方案3】:

    你的老师是绝对正确的。

    • 最多有n 推送,所以不能超过n 弹出。这证明了O(n) 的合理性。 [“在堆栈中循环的最后一次迭代”将只产生O(n)。]

    • 当一个奇数被推送时,它可以稍后被弹出[在你自己的“最后一个”示例中,除了一个之外的所有元素都可以被推送然后弹出]。

    【讨论】:

      【解决方案4】:

      很抱歉提供了这么多正确答案的答案,但用图表可能更容易解释。您对最坏情况的评估是正确的,堆栈以奇数构建,最后一个 nn-1 是偶数,导致堆栈完全清空。在这种情况下,完成工作的粗略图,垂直,水平时间为一个n

      最大工作量步是n,有n 步。确实问题出在O(n^2)。这对应于填充一个正方形n x n:\sum_{t=1}^{n} n = n^2 \in O(n^2)你的老师是对的;通过将工作分成两部分,您可以实现更紧密的绑定:sum_{t=1}^{n-1} 1 + n = n - 1 + n = 2n - 1 \in O(n)

      有人可能会问,内循环的运行时间是多少?最坏的情况也是O(n),因为堆栈为空。次n,是O(n^2)。在amortized analysis 中,您查看一系列操作。因此,您可以从高值中借用 a 来平衡它。这是O(1) 摊销步。

      【讨论】:

        猜你喜欢
        • 2014-06-05
        • 1970-01-01
        • 1970-01-01
        • 2014-06-12
        • 1970-01-01
        • 2021-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多