-2

I've just started learning time and space complexity and I'm having trouble in calculating it for this program.

void f(int n){
    int a[4] = {1, 1, 1, 1};
    for(int k = 0; k < n; k++){
        a[k % 4] *=3;
    }
    int** ptr = (int **)malloc(a[0]*sizeof(int*));
    for (int j = 0; j < a[0]; j++) {
        *(ptr+j) = (int*)malloc(j*sizeof(int));
        for(int k = 0; k < j; k++){
            printf("*");
        }
    }
}

I've tried to use the methods that I learned but im not sure how to use them correctly.

Can somebody explain me how to find the complexity of this example?
Thanks in advance for any help!

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • [How to ask homework question](https://meta.stackoverflow.com/questions/334822/how-do-i-ask-and-answer-homework-questions) and [Open letter to students with homework problems](https://softwareengineering.meta.stackexchange.com/questions/6166/open-letter-to-students-with-homework-problems) – Barmar Jan 10 '23 at 21:04
  • Don't use `*(ptr + i)`, use `ptr[i]`. – Barmar Jan 10 '23 at 21:06
  • What's the reason for `ptr`? You allocate it, but never use it for anything. – Barmar Jan 10 '23 at 21:07
  • This function is just for training – lafoti2742 Jan 10 '23 at 21:08
  • You basically have to figure out how `a[0]` grows as a function of `n`, since that bounds the second loop. `malloc()` itself is O(1). – Barmar Jan 10 '23 at 21:08
  • @Barmar: Re “`malloc()` itself is O(1)”: Source? There is no loop at all in a typical `malloc` implementation, except one with constant loop bounds? No searching a list or tree or other data structure for a block of suitable size? Even disregarding the fact the operating system has to clear memory when providing new memory to a process? – Eric Postpischil Jan 10 '23 at 21:48
  • None of that is a function of N. So it's asymptotically constant time as far as the caller is concerned. – Barmar Jan 10 '23 at 21:51
  • @EricPostpischil Clearing the memory would be O(n). But most calls to `malloc()` don't require getting memory from the OS, it's just reusing memory already in the heap. So it's in the noise. – Barmar Jan 10 '23 at 21:52
  • @Barmar: How does `malloc` find a block of sufficient size in its pool without using some form of loop? – Eric Postpischil Jan 10 '23 at 22:00
  • @EricPostpischil It uses some kind of loop, but the loop iterations are not a function of `N`. It's a black box, you can't account for it in the time complexity of the caller. – Barmar Jan 10 '23 at 22:06
  • @Barmar: You do not know whether it is a function of `n`; calling it repeatedly will affect its data structures, and it will have some varying behavior over the sequences of calls. If it is a black box, you cannot say it is O(1). – Eric Postpischil Jan 10 '23 at 22:12
  • @EricPostpischil Since it's a black box you can't say anything about its effect on the complexity. So you just ignore it. Just like you ignore the complexity of array indexing, arithmetic operations, etc. – Barmar Jan 10 '23 at 22:14
  • @Barmar: Re “Since it's a black box you can't say anything about its effect on the complexity. So you just ignore it.”: That is not a correct approach. Re “Just like you ignore the complexity of array indexing, arithmetic operations, etc.”: These are not ignored; the complexity is expressed in a model of [arithmetic complexity](https://en.wikipedia.org/wiki/Computational_complexity#Others) rather than the model of bit complexity. Bit complexity is the model used in computer science theory… – Eric Postpischil Jan 10 '23 at 22:20
  • … Arithmetic complexity is a practical model for characterizing performance of real-world programs that will not overflow their bounds, and it is understood that, if they needed to exceed their word size, the run-time would be different. If OP wants the bit complexity, then the complexity of array indexing and arithmetic operations cannot be ignored. – Eric Postpischil Jan 10 '23 at 22:20

1 Answers1

0

The first loop iterates n times. The body is a constant-time equation, so the loop is O(n).

Each time the loop cycles through the a array, it multiplies the elements by 3, so the result is that the value of each element is asymptotically proportional to 3n.

The only element that matters for the second loop is a[0]. So the outer loop iterates O(3n) times.

The inner loop iterates j times, where j goes from 0 to 3n-1. The formula for the sum of the sequence 1, 2, ... x is x * (x + 1) / 2, which is O(x2).

When you combine these, the resulting complexity is O((3n)2).

The space complexity is the same, since the total size of the arrays allocated in the loop are the same as the number of iterations of the inner loop.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Re “The time complexity of nested loops is the complexity of the outer loop times the complexity of the inner loop”: That may hold for simple loops, but it is not true in general, so it should not be stated as a principle without some contingency. If there are some interactions between the inner and outer loops, the total complexity may be different. – Eric Postpischil Jan 10 '23 at 21:31
  • Hey! Thanks for your help. Can you explain more about the way you combined them int the 5th paragraph? – lafoti2742 Jan 11 '23 at 13:30