【问题标题】:What is the big-o notation for this algorithm? [duplicate]该算法的大 O 符号是什么? [复制]
【发布时间】:2023-12-02 02:18:01
【问题描述】:

在循环中包含 N 乘法的算法的大 O 表示法是什么。

void testing(int n) {
    for(int i =0; i<n;i++) {
        n=n*2;
        System.out.println("hi"+n);
    }
}

【问题讨论】:

  • 如果n开头为零或负数,则立即结束;那是 O(1)。如果n 开始为正数,它将一直运行到n 溢出,所以我猜......这是一个较慢的 O(1)。
  • 这个运行无穷大,假设我们假设整数可以是任意大的,n &gt; 0。所以这里不存在时间复杂度的概念。
  • @WillemVanOnsem 我们是否假设整数可以任意大?它实际上会很快溢出。
  • @khelwood:显然这一切都取决于某些假设。例如,如果一个人使用BigIntegers,那么加法/减法/乘法就不会在 O(1) 中运行。但是,如果我们认为整数具有固定大小,那么严格来说,大量程序将在 O(1) 中运行。由于例如 Java 中的数组包含一个具有长度的字段,因此它的大小受到限制,因此对数组求和最多只能求和例如 2^64 项,因此运行恒定。
  • @user2478398 这不是为了分配,只是为了我的好奇心。正如我所看到的,如果循环内部是 n=n/2,它是 o(log n),因为它每次运行时都会减少步长。那么如果每次循环运行时乘法都会增加n。

标签: java time-complexity big-o


【解决方案1】:

我会尽量严谨地回答我的问题。

EDIT:忘了说,我们假设每个操作,如比较、赋值和乘法,都有O(1)

的复杂度

简而言之,该算法在大多数情况下都不会终止,因此没有为其定义复杂度。 复杂度是算法成本 C 的某种上限,说明 O(n) 复杂度意味着 C 0强>。非终止算法的成本是无限的,并且 inf > inf 是未定义的。

那么,让我们看看为什么你的算法是不终止的:

每次迭代,如果i ,我们继续。然而,每次迭代 n 都会乘以 2。在检查循环条件时,我们可以看到 in 的值之间的关系:n = n0x2^i,其中 n0n 的初始值。 因此,您的算法只会在n0 时终止,并且当这种情况发生时,它不会进入循环一次。

【讨论】:

  • 在什么情况下不会终止?您是否出于时间复杂度的目的假设没有整数溢出?
  • @Nexevis if n0 > 0,这不会终止,因为 i 永远不会被验证。在进行算法分析时,通常假设程序运行在类似图灵机的计算机上,这意味着它具有无限的内存和无限的数字大小能力。也就是说,如果您想考虑固定位整数大小,并将溢出视为正常行为,那么复杂性分析将变得相当复杂,因为您可能会遇到 n溢出剩余的情况> 仍然大于 i
【解决方案2】:

我尝试在我的 IDE 中运行您的代码,发现它是一个无限循环。 算法复杂度仅针对算法定义,根据(最常接受的)定义必须终止。当程序没有终止时,它就不是算法。所以它没有“算法时间复杂度”。

【讨论】:

  • 这不是一个无限循环。它会在n 溢出时结束。
  • n 用了什么?一旦int 溢出,它就会在我的IDE 中以n=1 终止。
  • 试试 n = 10
  • @Sanjeev Sharma 刚刚做了,对我来说,它不会与n=10 无限循环,一旦值为-1610612736,它就会终止
  • 是的,至少在 n >= 1 时是这样。
最近更新 更多