时间复杂度分析不一致

时间:2015-12-08 09:06:59

标签: algorithm time-complexity

我有这段代码:

int fun(int n)
{
  int count = 0;
  for (int i = n; i > 0; i /= 2)
     for (int j = 0; j < i; j++)
        count += 1;
  return count;
}

此代码的时间复杂度可以被视为O(n),因为O(n+n/2+n/4+...) = O(n)

按照这种逻辑,此片段的时间复杂度也可以被认为是O(n)

for(i = 1; i < n; i *= 2)
//O(1) statements

O(1+2+4+..+n/4+n/2) = O(n)以来。但由于循环运行log(n)次,因此它也可以log(n)

为什么前者不是:log(n)次外圈 * log(n)倍于内圈,log(n)log(n)

我做错了什么?

3 个答案:

答案 0 :(得分:2)

第一个片段的外部循环执行O(log n)次,每次迭代内部循环执行O(i)次。如果您对n / 2^k表单中的任意数量的术语求和,那么您将获得O(n)

第二段代码具有O(log n)O(1)次操作的迭代次数,对数量的常数之和仍为对数。

答案 1 :(得分:1)

第二个的时间复杂度应计算为一系列O(1+2+4+..+n/4+n/2) = O(n),因为该系列。

注意第一个。它被计算为一个系列,因为一个计算内部for循环执行的次数,然后添加所有这些(系列)以获得最终的时间复杂度。

i=n内部for循环执行n次时 当i=(n/2)内部for循环执行n/2次时 当i=(n/4)内部for循环执行n/4次时 等等..

但是在第二个中,没有要添加的系列。它只是一个公式(2^x) = n,其评估结果为x = logn

(2^x) = n此公式可以通过注意i1开头,当它变为2时获得2直到达到n 2
因此,需要了解2需要乘以n到达(2^x) = n的次数。
因此,公式x,然后解决$sample = 'UNITED STATES OF AMERICA'; function convert_str($str) { $except = array('of', 'in', 'is'); // Words you dont want to convert $str= strtolower($str); // apply strtolower to all return (in_array($str, $except)) ? $str : ucwords($str); // apply ucwords conditionally } $temp = explode(' ', $sample); // explode by space $new_temp = array_map('convert_str', $temp); // apply the function to every element echo implode(' ', $new_temp); // implode again

答案 2 :(得分:1)

在第一个示例中,您的循环中没有O(1)语句,因为您有for (int j = 0; j < i; j++) count += 1。如果在第二个示例中放置了第一个示例的相同内循环,则会回到相同的复杂程度。第一个循环不是O(n*log(n));这很容易证明,因为您可以在O(2n)中找到相当于O(n)的上限。