如何根据操作次数计算出时间复杂度

时间:2018-03-04 02:06:57

标签: algorithm time-complexity

所以我想知道如何根据操作次数计算出一段代码的时间复杂度( T(n)),例如下面的代码。< / p>

for( int i = n; i > 0; i /= 2 ) {
    for( int j = 1; j < n; j *= 2 ) {
        for( int k = 0; k < n; k += 2 ) {
            ... // constant number of operations
        }
    }
}

我确信它很简单,但我的讲师并没有很好地教授这个概念,我真的想知道如何计算时间的复杂性!

提前谢谢!

2 个答案:

答案 0 :(得分:1)

为了解决这个问题,一种方法是逐个分解三个循环的复杂性。

我们可以做的一个重要观察是:

(P):每个循环中的步数不依赖于其父循环的“索引”的值。

我们打电话

  • f(n)外部循环(1)
  • 中聚合的操作数 中间内环(2)
  • g(n)
  • h(n)位于最内圈(3)。

    for( int i = n; i > 0; i /= 2 ) {            // (1): f(n)
        for( int j = 1; j < n; j *= 2 ) {        // (2): g(n)
            for( int k = 0; k < n; k += 2 ) {    // (3): h(n)
               // constant number of operations  // => (P)
            }
        }
    }
    

循环(1)

步数
i获取值nn/2n/4,...等,直到n/2^k 2^k大于{{{{}} 1}}(n),这样2^k > n,此时你退出循环。

另一种说法是你有步骤1(n/2^k = 0),步骤2(i = n),步骤3(i = n/2),......步骤{{1} }(i = n/4),然后退出循环。这些是k - 1步骤。

现在i = n/2^(k-1)的价值是多少?观察k。这会使k或松散地说n - 1 <= 2^k < n <=> log2(n - 1) <= k < log2(n) <= INT(log2(n - 1)) <= k <= INT(log2(n))

每个步骤的费用
现在每个步骤有多少次操作?

在步骤k = INT(log2(n)),根据我们选择的符号和属性(P),它是k = log2(n)

循环(2)

步数
你有步骤(1)(i),步骤(2)(g(i) = g(n)),步骤(3)(j = 1)等等,直到你到达步骤(p)({{ 1}})其中j = 2被定义为j = 4的最小整数,或松散地说j = 2^p

每个步骤的费用
根据我们选择的符号和属性(P),步骤p的费用为2^p > n

循环(3)

步数
我们再次计算步骤:(1):log2(n),(1):j,(2):h(j) = h(n),...,k = 0。这相当于k = 2步。

每个步骤的费用
由于(P),它是常数。我们称之为常数k = 4

所有循环

汇总操作的数量是

k = n - 1 or k = n - 2

所以n / 2

答案 1 :(得分:0)

编写方法,添加计数器,返回结果:

int nIterator (int n) {
    int counter = 0;
    for( int i = n; i > 0; i /= 2 ) {
        for( int j = 1; j < n; j *= 2 ) {
            for( int k = 0; k < n; k += 2 ) {
                ++counter;
            }
        }
    }
    return counter;
}

快速增加N的协议,并以可读的方式记录结果:

int old = 0;
for (int i = 0, j=1; i < 18; ++i, j*=2) {
    int res = nIterator (j);
    double quote = (old == 0) ? 0.0 : (res*1.0)/old;
    System.out.printf ("%6d %10d %3f\n", j, res, quote);    
    old=res;
}

结果:

     1          0 0,000000
     2          2 0,000000
     4         12 6,000000
     8         48 4,000000
    16        160 3,333333
    32        480 3,000000
    64       1344 2,800000
   128       3584 2,666667
   256       9216 2,571429
   512      23040 2,500000
  1024      56320 2,444444
  2048     135168 2,400000
  4096     319488 2,363636
  8192     745472 2,333333
 16384    1720320 2,307692
 32768    3932160 2,285714
 65536    8912896 2,266667
131072   20054016 2,250000

因此n增加了2倍,计数器在开始时增加超过2 2,但随后迅速减少到某个东西,不会高于2.这可以帮助您找到方法。