【问题标题】:Time Complexity Of This Code Snippet此代码片段的时间复杂度
【发布时间】:2015-03-19 22:20:59
【问题描述】:

最近碰到一个代码sn-p:

int i = 1;
while (N > 1)
{
        N = N / i;
        i = i + 1;
}

观察,很明显i 线性增加,i 在循环的每个运行时除以N,因此我们可以说N 作为一个反函数的函数减少一个阶乘。

我们如何用 theta 表示法来表示它,因为 inverse factorial 并不是为每个自然数 N 定义的?我们是否必须使用该函数的近似上限和下限就足够了?

【问题讨论】:

  • 5 的反阶乘是多少? @FreeNickname
  • 对不起,我的错。我误解了你。出于某种原因,我想到了 1/n!是一个反阶乘。我现在将删除我的评论。
  • 您也可以尝试在math 上提问。告诉他们你来自cs背景。我发现它们非常有帮助。 (只是要明确一点:我不是说这是题外话)

标签: algorithm time-complexity big-theta


【解决方案1】:

好吧,我不确定,但我会试一试。 阶乘本质上是gamma function。伽马函数不仅适用于自然数,也适用于实数。因此,理论上存在一个反伽马函数,它是为未定义阶乘的情况定义的(例如,我们不知道 5 的反阶乘,但我们知道,反伽马函数5 将是两点左右的东西)。根据MathOverflow的说法,反伽马函数没有精确的公式,但有近似解。

假设存在反伽马函数,我们将其写为InvGamma(N)。它是一个实数(可能是 R+,但我不确定,现在它并不重要,因为我们的 N 始终是正数,除了 N == 0 的情况,我现在将忽略它)。

当我们处理复杂性时,我们可以像使用其他返回实数的函数一样使用它:我们可以floor它(向下舍入)。就像我们处理log 复杂性一样。我以前用方括号写(即log(15) = 1.18[log(15)] = 1)。

那么我相信你的 sn-p 的复杂度应该是O([InvGamma(N)])

更新:(受@6502 的回答启发):注意如果N 是一个整数(在代码sn-p 中没有提到),那么每一步都会进行舍入,它以一种复杂的方式改变了复杂性。上述解决方案适用于真正的Ns。

【讨论】:

  • 伽马反函数实际上是令人信服的。谢谢。但是,唯一的缺点是它返回多个值。
  • @ShauryaChats,确实如此。解决方法是取最大的值。不幸的是,我不确定可以使用什么符号来正确执行此操作。我想,我会保持原样。在我看来,这意味着什么很清楚。并且,例如,sqrt 还返回多个值(一个正值和一个负值),它仍然像 O(sqrt(N)) 一样用于复杂性函数。
【解决方案2】:

阶乘对除负整数之外的所有复平面的“自然”扩展称为"gamma function" 和所有非负整数gamma(n) = (n-1)!

因此,您可以反转 gamma 的一部分来计算所需的大致迭代次数,但我不确定这会导致迭代次数的 exact 计算,因为在该代码中有每一步都进行舍入操作。

【讨论】:

  • 关于每一步的舍入操作的要点。我们不知道N 的类型。但我同意,它很可能是某种integer
  • @FreeNickname 浮点运算也会导致舍入!
  • @Rerito,是的,确实如此,但在计算复杂度时通常会忽略浮点运算舍入,否则我们将无法计算一半算法的复杂度。
猜你喜欢
  • 2018-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 2015-03-31
  • 1970-01-01
相关资源
最近更新 更多