【问题标题】:Confuse with log(n) behaviour与 log(n) 行为混淆
【发布时间】:2018-06-03 17:40:25
【问题描述】:
s=0; 
for(i=1;i<n;i=i*2) 
{ 
    for(j=0;j<n;j++)
    {
        s=s+i*j;
    } 
    s=s+1;
}

我正在尝试确定上述算法的大复杂度。外部循环从 1 开始并运行到 ni 中的计数器在每次迭代中翻倍,因此这是一个 log(n ) 行为。内部循环从 0 运行到 n,具有 O(n) 行为。我很困惑是否是 O(n * log(n)),顺序是否重要? j 也是从 0 开始,而不是从 1 开始,所以这不可能是 O(n * log(n))

【问题讨论】:

  • s += 1替换你对s的分配; s 最后的值是你的 O() 应该代表的值。这可能会帮助您确定订单是否重要。 (请注意,对于某些代码,无论在本例中是否如此。)

标签: algorithm data-structures time-complexity big-o


【解决方案1】:

在这种情况下,内循环独立于外循环。所以我们可以只计算外循环运行的次数,然后将其乘以内循环运行的次数,这就是复杂度。

没有。外部循环运行的次数是log2(n),因为每次都将数字乘以2

没有。内循环运行的次数总是n

因此,复杂度将是O(nlog2(n))

【讨论】:

    【解决方案2】:

    在这样的简单情况下,您实际上可以计算内部循环运行了多少次。随着n 的变化,它将很好地指示渐近行为。这是一个快速的 javascript 示例:

    function count(n) {
        let count=0; 
        for(i=1; i<n; i=i*2) 
        { 
            for(j=0;j<n;j++)
            {
                count++
            } 
           
        }    
        return count
    }
    let n = 1024
    console.log("n:", n, "iterations:", count(n),"nlog(n):", Math.log2(n) * n)
    
    n = 32768
    console.log("n:", n, "iterations:", count(n),"nlog(n):", Math.log2(n) * n)
    
    n = 1048576
    console.log("n:", n, "iterations:", count(n),"nlog(n):", Math.log2(n) * n)

    对我来说,这种行为看起来像 O(nlog(n))。此外,执行log(n) 循环,每个循环执行n 迭代将是O(nlog(n)),因为n * log(n) === log(n) * n

    【讨论】:

      【解决方案3】:

      我很困惑是不是 O(n * log(n))

      是的,你是对的。就像你解释的那样,外循环有 log(n) 次迭代,内循环有 n 次迭代,所以 O(log(n) * n) 总复杂度。

      顺序是否重要?

      这里没关系。例如O(log(n) * n) == O(n * log(n))

      j 也是从 0 开始,而不是从 1 开始,所以这不可能是 O(n * log(n))

      不会影响复杂性。当 N 趋于无穷时,从 0 开始或从 1 开始都没有区别。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-21
        • 1970-01-01
        • 2014-07-09
        • 1970-01-01
        相关资源
        最近更新 更多