Table of contents
1.
Introduction
2.
Time Complexity
3.
Problem Statement 1
3.1.
Analysis
4.
Problem Statement 2
4.1.
Analysis
5.
Frequently Asked Questions
5.1.
What is the Big O-notation?
5.2.
Are running time and time complexity the same?
5.3.
What are asymptotic notations?
5.4.
What are Big-Omega Ω-Notation and big-Theta Θ-Notation?
5.5.
What is the best time complexity in the worst case?
6.
Conclusion
Last Updated: Oct 10, 2024
Medium

Interesting Time Complexity Questions in C++

Author Malay Gain
1 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Besides solving coding problems, one should be aware of the time complexity of the implemented algorithm so that it can be optimized further.

An Interesting Time Complexity Question in C++ | Part 1

As a programmer, when trying to solve a problem and create an algorithm for the problem, you must remember that there can be multiple solutions for that particular, depending on the approach.

So if there are many solutions to a problem in the world of programming, then how to decide which solution is good or not? Well, that depends on the application's requirements, like whether the application should be efficient in terms of space or time. Space and time are the two most important factors in judging the efficiency of a program or algorithm. To learn more about space and time complexity, you can go to time complexity as well as space complexity.

This blog will discuss two problem statements to showcase the time complexity. But before we look into the problems, we need to understand time complexity. 

Time Complexity

Time complexity is the concept we use to analyze the time taken by an algorithm or program with respect to the input size. Remember that the time complexity is not the actual time taken by the program to generate the output; it is a theoretical concept that gives us an idea of how efficient the algorithm is with respect to the input size.

The actual running time of an algorithm or program depends on various factors like the machine's computational power. We cannot generate the running time of the algorithm. 

To solve this problem, we use the concept of time complexity to get a rough estimate of the time with respect to the input of a program. Our goal is to write an efficient program in terms of time when we provide large data as input to the program.

To judge the algorithm's efficiency, we can classify it into the following area depending on the algorithm's approach. Any algorithm can be classified into some type based on its complexity. See the classes mentioned below. We will talk about the Big-O time complexities because it is the average worst time taken which is considered an excellent way to judge an algorithm's efficiency.

Big O-notation

Here n is the size of the input, a is the exponent integer, and k is the degree of n.

Let's see the graphical representation of the above complexities and observe how each of them behaves for a particular input size.

complexity graph

Before we talk about the representation, let's see what each color of the line in the graph represents. You can see the line color on the left side of the complexity.

time complexities

On the x-axis, we are measuring the user input, and on the y-axis time complexity. From all the lines, we can observe that the blue line gives us linear time as we go further on the x-axis concerning the y-axis. 

The large input size does not significantly affect the blue line, which is Logarithmic: O(log n) time. As you can see, the rest of the lines increase significantly as the input size increases for the blue line. This shows that the logarithmic time complexity is the best average time to process the input.

To learn more about Big-O notation, check out the below video.

Now that we have understood the basics of time complexity let's analyze the time complexity question.

Also see,  Euclid GCD Algorithm

Problem Statement 1

Our task will analyze the following code or function to calculate the time complexity to know if this code is suitable for large input sizes depending on which category it will fall into. Once we analyze this time complexity question, we will again analyze this statement with a different approach.

void fun1(int n)
{
	for (int i = 1; i < n; i++)
	{
		for (int j = 1; j < n; j+=i)
		{
			cout << i << " " << j << endl;
		}
	}
}


Code:

#include <iostream>
using namespace std;

void fun1(int n)
{
	for (int i = 1; i < n; i++)
	{
		for (int j = 1; j < n; j+=i)
		{
			cout << i << " " << j << endl;
		}
	}
}

// Main function

int main()
{
	fun1(10);

	return 0;
}
You can also try this code with Online C++ Compiler
Run Code


Output

problem statement 1 output

Analysis

In the time complexity question, the inner loop of fun1() will run (n/i) times for each value of i. 

For i=1,

the inner loop will run (n/1) times; 

for i=2,

the inner loop will run (n/2) times; 

……………………………

For i=n,

the inner loop will run (n/n) times; 

So, the total number of operations in the function

=(n/1 + n/2 + n/3 + n/4 + n/5………… + n/n)

=n(1/1 + 1/2 + 1/3 + 1/4 + 1/5………… + n/n)
 

Value of (1/1 + 1/2 + 1/3 + 1/4 + 1/5………… + n/n) expression can be approximated as (log n)

So, the total number of operations= n(log n).

The function's time complexity in Big O-notation is O(nlog n).

Read More - Time Complexity of Sorting Algorithms

Problem Statement 2

Now we will again try the observe the above problem, but this time the inner loop will run until log(i) times so that we can observe both statements and decide which code is better depending on the time complexity.

void fun2(int n)
{
	for (int i = 1; i < n; i++)
	{
		for (int j = 1; j < log(i); j++)
		{
			cout << i << " " << j << endl;
		}
	}
}


Code:

#include <bits/stdc++.h>
using namespace std;

void fun2(int n)
{
	for (int i = 1; i < n; i++)
	{
		for (int j = 1; j < log(i); j++)
		{
			cout << i << " " << j << endl;
		}
	}
}

// Main function

int main()
{
	fun2(10);

	return 0;
}
You can also try this code with Online C++ Compiler
Run Code


Output

problem statement 2 output

Analysis

In the time complexity question, the inner loop will run log(i) times for each value of i. 

For i=1,

the inner loop will run log(1) times; 

for i=2,

the inner loop will run log(2) times; 

……………………………

For i=n,

the inner loop will run log(n) times; 

So, the total number of operations in the function

=(log(1)  + log(2)  + log(3) + log(4) + log(5) ………… +log(n))

=log(1*2*3*..........*n) because log m*n = log m + log n )

=log(n!)

The time complexity of the above function in terms of Big O-notation is O(log n!).
 

Now we have analyzed the time complexity question with two different approaches, and we can observe that approach 1 is more suitable because in that, we got O(nlogn) complexity, and in the second approach, we got O(log n!).

Must Read Lower Bound in C++

Frequently Asked Questions

What is the Big O-notation?

Big O-notation is one of the asymptotic notations in time complexity that we use to measure the efficiency of an algorithm in worst-case analysis.

Are running time and time complexity the same?

Time complexity is a theoretical concept that gives us an idea of how efficient the algorithm is with respect to the input size, where the running time of an algorithm or program depends on various factors like the machine's computational power, input size, and many other factors.

What are asymptotic notations?

Asymptotic notations are the mathematical notation we use to label an algorithm after calculating the time complexity for the input size. Big-O, Big-Omega, and Big-Theta are the types of asymptotic notations.

What are Big-Omega Ω-Notation and big-Theta Θ-Notation?

Big-Omega Ω-Notation is the asymptotic lower bound of an algorithm, and big-Theta Θ-Notation is the asymptotic tight bound (i.e., average-case time complexity) of an algorithm.

What is the best time complexity in the worst case?

The O(1) is the best average time because the input size does not affect the algorithm.

Conclusion

This article has covered an interesting time complexity question. We have shown the approach of time complexity analysis of a program. We have also discussed in brief the time complexity and its notations.

To learn more about time complexity, check out the following articles:

To learn more about Data Structures and Algorithms, you can enroll in our DSA in C++ Course.

Live masterclass