【问题标题】:What is the running time of the algorithm? is it O(sqrt(n)) or O(log(n))?算法的运行时间是多少?是 O(sqrt(n)) 还是 O(log(n))?
【发布时间】:2020-01-08 16:20:48
【问题描述】:

编辑:约束值范围 [2,1000000000] 和 a

 def sqrtoccurrence(a: Int, b: Int): Int = {
        val sqrtA = Math.ceil(Math.sqrt(a)).toInt
        val sqrtB = Math.floor(Math.sqrt(b)).toInt
        if(sqrtA > sqrtB) 0
        else 1 + sqrtoccurrence(sqrtA, sqrtB)      
      }

是 O(sqrt(n)) 还是 O(log(n))?我不擅长计算递归运行时间。我知道它的树的深度以及递归函数被调用的次数。在这种情况下,恒定工作 sqrt 会影响多少,所以是否可以忽略它?但也许我错了。有很大帮助的解释。 谢谢

【问题讨论】:

  • n 在这里代表什么?我在您的代码或算法中看不到 n
  • 这段代码似乎有缺陷。如果您设置 a = 1,它将永远不会完成。如果 a > 1,那么它似乎是 O(sqrt(n)) 尽管如果 a 和 b 是随机数,它将立即终止大约一半的时间.

标签: algorithm scala performance runtime big-o


【解决方案1】:

以下是我对必要运行时间的推理。在a > b 的最佳情况下,不需要递归,因此它是O(1) 操作。当a <= b 使ceil(sqrt(a)) > floor(sqrt(b)) 成为可能时,唯一可以使aab 重复的sqrt() 将它们的差异减小到小于舍入误差。

在最坏的情况下,我们正在研究大 b 的重复 sqrt() 如何“缩小”以满足小 a 的终止要求。因此,我将输入n 上的函数的运行时间描述为:

T(n) = T(sqrt(n)) + C  // where C is O(1)

要计算必要递归的近似数量r,我们可以查看递归结束时n 的重复sqrt() 的最终值,例如m,并建立一个方程如下逻辑:

m 是将sqrt() 应用于n r 次的结果

因此,

(..(m^2)^2)^2 ... )^2 = n  // `r` times of `^2`

m^(2^r) = n

这意味着:

2^r = log(n)     // log base `m`

r = log(log(n))  // outer log base `2`

因此,时间复杂度为O(log(log(n)))


sqrtoccurrence(2, 10)           // 1
sqrtoccurrence(2, 100)          // 2
sqrtoccurrence(2, 1000)         // 3
sqrtoccurrence(2, 1000000)      // 4
sqrtoccurrence(2, Int.MaxValue) // 4

def log2(x: Double): Double = math.log(x) / math.log(2)

log2(log2(10))           // 1.732
log2(log2(100))          // 2.732
log2(log2(1000))         // 3.317
log2(log2(1000000))      // 4.317
log2(log2(Int.MaxValue)) // 4.954

【讨论】:

  • a=b=2^17 。然后sqrt(a)=sqrt(b) = 362.03;这意味着f(a,b) = 0 并且仅在一次迭代中计算,但log(log(n)) = 4.09。随着 n 变大,情况会变得更糟。也许log log n 是当 a 和 b 的形式为 2^k 时的复杂度。
  • @jrook,总是有最好的情况(在这种情况下为a >= b)运行时间远低于大 O 建议的时间。但请记住,即使 n2^17 大得多,log(log(n)) 也几乎不会超过 4.9。事实上,log(log(Int.MaxValue)) < 5.0。这与我对sqrtoccurrence 与小a 和大b 的简短测试结果一致,这是时间复杂度近似所基于的非最佳情况。
  • 嗨,leo,我认为这是正确的答案,但请您解释一下答案。你是如何推导出 Olog(log(n)) 的。特别是“我要断言 ceil(sqrt(a)) 相对于 floor(sqrt(b)) 的价值增益率将主要取决于 sqrt() 的“收缩”率”
  • @jrook big-O 表示最坏的情况,而不是最好的情况。 f(a,b) =0 是最好的情况,它不是 O 表示法。
  • @gamer,我已经扩展了答案,希望能让解释更清楚。
【解决方案2】:

从我们得到的另一个答案

T(n) = T(sqrt(n)) + C

现在让

2^m = n

重写

T(2^m) = T(sqrt(2^m)) + C
       = T(2^(m/2)) + C

让我们定义一个新函数

S(m) = T(2^m)

然后

S(m) = T(2^m)
     = T(2^(m/2)) + C
     = S(m/2) + 2C

我们现在知道了

S(m) = O(log m)

因此

T(n) = T(2^m) = S(m) = O(log m) = O(log log n)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 2015-12-19
    • 2019-11-21
    • 1970-01-01
    • 2019-12-13
    • 2011-12-11
    • 1970-01-01
    相关资源
    最近更新 更多