一段代码的大O复杂性

时间:2015-05-14 09:00:58

标签: algorithm time-complexity

我在算法设计中有一个关于复杂性的问题。在这个问题中给出了一段代码,我应该计算这段代码的复杂性。 伪代码是:

for(i=1;i<=n;i++){
    j=i
    do{
        k=j;
        j = j / 2;
    }while(k is even);
}

我为一些数字尝试了这个算法。我得到了不同的结果。例如,如果n = 6,则此算法输出如下所示

i = 1 -> executes 1 time
i = 2 -> executes 2 times
i = 3 -> executes 1 time
i = 4 -> executes 3 times
i = 5 -> executes 1 time
i = 6 -> executes 2 times

它没有常规主题,我该如何计算?

5 个答案:

答案 0 :(得分:99)

其他答案给出的上限实际上太高了。该算法具有O(n)运行时,其上限比O(n * logn)更严格。

证明:让我们计算内循环将执行的总迭代次数。

外循环运行n次。内部循环至少运行一次。

  • 对于偶数i,内循环运行至少两次。这种情况发生n/2次。
  • 对于可被4整除的i,内循环至少运行三次。这种情况发生n/4次。
  • 对于可被8整除的i,内循环至少运行四次。这种情况发生n/8次。
  • ...

因此内循环运行的总次数为:

n + n/2 + n/4 + n/8 + n/16 + ... <= 2n

内循环迭代的总量在n2n之间,即它是Θ(n)。

答案 1 :(得分:6)

你总是假设你在每个级别都遇到了最糟糕的情况。
现在,你迭代一个包含N个元素的数组,所以我们先从O(N)开始 现在假设你的i总是等于XX总是均匀(记住,每次都是最坏的情况)。你需要划分多少次{{1通过X获取2? (当偶数达到1时,这是偶数停止除法的唯一条件。) 换句话说,我们需要解决这个问题 1 X/2^k = 1X=2^k k=log<2>(X) 这使我们的算法采用O(n log<2>(X))步骤,可以很容易地写成O(nlog(n))

答案 2 :(得分:4)

对于这样的循环,我们不能分离内循环和外循环的计数 - &gt;变量被收紧了!

因此,我们必须统计所有步骤。

事实上,对于外循环的每次迭代(在angular.module('appName') .service('GetDataService', function($http, $q WebServiceURL) { this.getData = function(ServiceParameter) { var defer = $q.defer(); $http.get(WebServiceURL + ServiceParameter) .then(function(res){ defer.resolve(res.data); }, function (err) { defer.reject(err)}); return defer.promise; }; 上),我们将有

i

其中1 + v_2(i) steps 是2-adic估值(例如参见:http://planetmath.org/padicvaluation),其对应于v_2的素因子分解中2的幂。

因此,如果我们为所有i添加步骤,我们会得到以下步骤的总数:

i

然后我们看到步数 完全

n_steps = \sum_{i=1}^{n} (1 + v_2(i)) 
        = n + v_2(n!)    // since v_2(i) + v_2(j) = v_2(i*j)
        = 2n - s_2(n)    // from Legendre formula (see http://en.wikipedia.org/wiki/Legendre%27s_formula with `p = 2`)

由于n_steps = 2n - s_2(n) 是基数s_2(n)n的数字之和,因此可以忽略不计(最多2,因为基数log_2(n)中的数字是与2相比,0或1以及最多log_2(n)个数字。

因此,算法的复杂性等同于n

n

许多其他解决方案中陈述的n_steps = O(n) ,但数量较少!

答案 3 :(得分:0)

让我们从最坏的情况开始:

如果你继续除以2(积分),你不需要停下来直到你 得到1.基本上使步数取决于位宽, 你发现使用两个对数的东西。所以内部是log n。 外部显然是n,所以总共N log N

答案 4 :(得分:0)

do循环将j减半,直到k变为奇数。 k最初是j的副本,是i的副本,因此do运行1 {+ {1}}的权力,其中2除以:

  • i = 1是奇数,所以它通过i循环,
  • i = 2除以2,因此1 + 1,
  • i = 4除以2,因此1 + 2等

这最多可以执行1 + log(i)do次(以2为基数的对数)。

do循环从{1}到for迭代i,因此上限为n次(1 + log n),即O(n log n) )。