Time complexity of the program?

2019-09-20 04:37发布

1 i ← 1
2  while i < n/4
3   do
4    j ← 2i
5     while j < n
6       do
7         j ← j + 1
8     i ← i + 1


b) 1 i ← n
   2 while i > 1
   3   do
   4    j ← i
   5    while j < n
   6      do
   7        j ← 2j
   8    i ← i − 1


 c) 1 i ← 1
    2 while i < n
    3   do
    4     j ← 0
    5     while j ≤ i
    6       do
    7         j ← j + 1
    8     i ← 2i

Given these three programs, what would be the easiest approach in finding the time complexity for each one of these? I can tell that the first one is probably going to be O(n^2). But is there an easy approach to these to solve it consistently? I have an exam about it tomorrow.

1条回答
来,给爷笑一个
2楼-- · 2019-09-20 05:10

(I'll ignore off-by-1, rounding etc. in the summation limits)


A)

In the inner loop you do n - 2i - 1 operations. In the outer loop you do n/4 - 1. So the complexity is:

enter image description here

So your answer to the first one is correct.


B)

In the inner loop, j gets doubled every time, so grows exponentially; therefore the inner loop takes logarithmic time - log (n / i). (base 2 but ignore WLOG). The division by i inside is because j starts from i, so is equivalent to starting from 1 and growing up to n / i. In the outer loop you do n - 1 ops.

enter image description here

(Last step is from Stirling's approximation)


C)

In the inner loop you do i + 1 ops. In the outer loop i grows exponentially from 1 to n, so log n.

enter image description here


N.B. I notice the significant discrepancy with TypeKazt's answers; this illustrates you can't simply "multiply" the inner loop's complexity with that of the outer loop, and that the boundary conditions for the inner loop are deterministically important.


EDIT: As added proof to my bold accusations against TypeKazt (hehe sorry buddy), here is some test data I got from a C# implementation:

enter image description here enter image description here enter image description here

As you can see, the complexity of A (linear scale) is O(n^2), whereas those of B and C (log-log scales) are linear.

Code:

static int A(int n)
{
   int c = 0;
   for (int i = 0; i < n / 4; i++)
      for (int j = 2 * i; j < n; j++)
         c++;
   return c;
}

static int B(int n)
{
   int c = 0;
   for (int i = n; i > 1; i--)
      for (int j = i; j < n; j *= 2)
         c++;
   return c;
}

static int C(int n)
{
   int c = 0;
   for (int i = 1; i < n; i *= 2)
      for (int j = 0; j <= i; j++)
         c++;
   return c;
}

P.S. I know SO's policy is not to babysit people, but I for one learn well by examples, so I hope this will help you to understand a simple analytical approach to complexity analysis.

查看更多
登录 后发表回答