Easy way to calculate time complexity

"I am currently a Software Engineering student at ALX. I'm passionate about technology and enjoy conducting research to find answers on my own. I have a natural inclination to ask 'WHY' more often than 'HOW'.
"While working on projects at ALX, I have acquired a wealth of interesting and diverse knowledge about software engineering and computer science in general. Therefore, I needed a place to store and save all this information, allowing me to refer back to it whenever I forget."
Using the example below for illustration
void f(int n)
{
int i;
int j;
for (i = 0; i < n; i++)
{
if (i % 2 == 0)
{
for (j = 1; j < n; j = j * 2)
{
printf("[%d] [%d]\n", i, j);
}
}
else
{
for (j = 0; j < n; j = j + 2)
{
printf("[%d] [%d]\n", i, j);
}
}
}
}
Step 1: Identify the loops
- We have two nested loops in the function: an outer loop and an inner loop.
Step 2: Determine the number of iterations in each loop
Outer loop: The outer loop runs from
i = 0toi = n-1, so it hasniterations.Inner loop (when
iis even): The inner loop starts fromj = 1and doublesjin each iteration until it reachesn. The values ofjin this loop are 1, 2, 4, 8, ..., up ton-1, or the largest power of 2 that is less thann. The number of iterations in this loop can be approximated aslog2(n).Inner loop (when
iis odd): The inner loop starts fromj = 0and incrementsjby 2 in each iteration until it reachesn-1. The values ofjin this loop are 0, 2, 4, 6, ..., up ton-2, or half of the values in the range 0 ton-1. The number of iterations in this loop can be approximated asn/2.
Step 3: Compute the total number of iterations
Since the inner loop's behavior depends on the value of
i(even or odd), we need to consider both cases:When
iis even, the number of iterations in the inner loop is approximatelylog2(n).When
iis odd, the number of iterations in the inner loop is approximatelyn/2.
The total number of iterations can be computed by adding the number of iterations in the inner loop (even case) and the number of iterations in the inner loop (odd case) for each value of
i.
Step 4: Compute the time complexity
Based on the total number of iterations, we can determine the time complexity. Generally, we look at the dominant term in the number of iterations.
The time complexity of the function will be the dominant term.
Now, let's put it all together:
The outer loop has
niterations (O(n)).The number of iterations in the inner loop when
iis even is approximatelylog2(n)(O(log n)).The number of iterations in the inner loop when
iis odd is approximatelyn/2(O(n)).
Now, let's see how these inner loops contribute to the overall time complexity:
When
iis even, the time complexity of the inner loop is O(log n) since it runslog2(n)times.When
iis odd, the time complexity of the inner loop isO(n)since it runsn/2times.
When analyzing time complexity, we focus on the most significant term that dominates the overall growth rate. In this case, O(n) is more significant than O(log n). So, when combining both cases (even and odd values of i), the overall time complexity of the function is O(n) * O(n) = O(n^2).
The presence of the O(n) term from the inner loop with odd i values makes the overall time complexity of the function O(n^2).
Using the example below to touch all the time complexity functions available
void complexFunction(int n) {
int i, j, k;
// O(1) operation
printf("O(1) operation\n");
// O(n) loop
for (i = 0; i < n; i++) {
// O(1) operation
printf("[%d] O(1) operation\n", i);
}
// O(n^2) nested loop
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
// O(1) operation
printf("[%d][%d] O(1) operation\n", i, j);
}
}
// O(n^3) nested loop
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
for (k = 0; k < n; k++) {
// O(1) operation
printf("[%d][%d][%d] O(1) operation\n", i, j, k);
}
}
}
// O(log n) loop
for (i = 1; i < n; i *= 2) {
// O(1) operation
printf("[%d] O(1) operation\n", i);
}
// O(n log n) nested loop
for (i = 1; i < n; i++) {
for (j = 1; j < n; j *= 2) {
// O(1) operation
printf("[%d][%d] O(1) operation\n", i, j);
}
}
}
Explanation:
The function starts with an O(1) operation (constant time complexity).
The first loop runs
ntimes, giving it a time complexity of O(n).The second nested loop runs
n^2times, resulting in a time complexity of O(n^2).The third nested loop runs
n^3times, leading to a time complexity of O(n^3).The fourth loop runs
log ntimes, making it O(log n).The fifth nested loop runs
n * log ntimes, giving it a time complexity of O(n log n).
The Final Time Complexity(of all the time complexity functions)
To determine the overall time complexity of the function, we need to consider the time complexities of all the loops present in the function and find the dominant term.
Let's break down the time complexities of each part:
O(1) operation: This has constant time complexity and doesn't depend on the value of
n. It doesn't affect the overall time complexity.O(n) loop: This loop runs
ntimes, contributing O(n) to the overall time complexity.O(n^2) nested loop: This nested loop runs
n^2times, contributing O(n^2) to the overall time complexity.O(n^3) nested loop: This nested loop runs
n^3times, contributing O(n^3) to the overall time complexity.O(log n) loop: This loop runs
log ntimes, contributing O(log n) to the overall time complexity.O(n log n) nested loop: This nested loop runs
n * log ntimes, contributing O(n log n) to the overall time complexity.
Now, let's compare the complexities:
O(n) < O(n log n) < O(n^2) < O(n^3)
The most significant term that dominates the overall time complexity is O(n^3) since it grows faster than all the other terms. Therefore, the overall time complexity of the function is O(n^3)



