15.3 For Loops

Count, count, count...

Now that we've seen some runtime analysis, let's work through some more difficult examples. Our goal is to get some practice with the patterns and methods involved in runtime analysis. This can be a tricky idea to get a handle on, so the more practice the better.

Scan Example:

Last time, we saw the function dup1, that checks for the first time any entry is duplicated in a list:

int N = A.length;
for (int i = 0; i < N; i += 1)
   for (int j = i + 1; j < N; j += 1)
      if (A[i] == A[j])
         return true;
return false;

We have two ways of approaching our runtime analysis:

  1. Counting number of operations

  2. Geometric visualization

Method 1: Count Number of Operations

Since the main repeating operation is the comparator, we will count the number of "==" operations that must occur.

The first time through the outer loop, the inner loop will run N1N-1times. The second time, it will run N2N-2 times. Then N3N-3, N4N-4, .... all the way till running the inner loop exactly 11 time when i = N1N - 1. In the worst case, we have to go through every entry, and the outer loop runs NN times.

Then, let CC = total number of "==" operations that have occurred. The number of comparisons is:

C=1+2+3+...+(N3)+(N2)+(N1)=N(N1)/2C = 1 + 2 + 3 + ... + (N - 3) + (N - 2) + (N - 1) = N(N-1)/2

where N(N1)/2N(N-1)/2 is part of the N2N^2 family.

Since "==" is a constant time operation, the overall runtime in the worst case is θ(N2)\theta(N^2).

Method 2: Geometric Visualization

We can also approach this from a geometric view.

Let's draw out when we use == operations in the grid of i,ji,jcombinations:

We see that the number of == operations is the same as the area of a right triangle with a side length of N1N - 1. Since area is in the N2N^2​​ family, we see again that the overall runtime is θ(N2)\theta(N^2).

Last updated