Skip to main content

Time Complexity in One Shot | MyCodingNetwork

 


After exploring various aspect of programming, it's important to understand and calculate the amount of time our code takes to execute for a given size of input. The concept needed for this is called Time Complexity. In this article we will be exploring various aspects of Time Complexity and also solve numerous questions on it, so that we can have strong foundation of one of the most important aspect in the world of DSA.

Introduction

For a beginner the first question that should come to his/her mind is, "what is time complexity?". The answer is pretty simple, it is a measure of the amount of time an algorithm takes to complete as a function of the size of the input. It is important to analyze the time complexity of an algorithm because it helps us to compare different solutions and choose the most efficient one for a given problem. 

In simple words (just to understand), one way to measure the time complexity of an algorithm is to count the number of iterations it performs. We can express the time complexity of an algorithm as a function of n, where n is the input size...

Time complexity is commonly represented using big O notation, which describes the upper bound of the growth rate of an algorithm's running time.

For example, consider the following algorithm that prints all elements of an array.


int print(int arr[], int n)

{

for(int i=0; i<n;i++)

System.out.println(arr[i]);

}

The time complexity of this algorithm is O(n), where n is the length of the array. This means that the algorithm performs n operations/iterations.




Classes of Time Complexity

Analyzing the time complexity of algorithms helps us understand how well an algorithm will perform and scale as the size of the input grows. This can help us choose the most efficient algorithm for a given task. There are different classes of time complexity that are commonly used to classify algorithms, such as constant, logarithmic, linear, polynomial, exponential, etc. Here, an algorithm with constant time complexity always takes the same amount of time regardless of the input size, while an algorithm with exponential time complexity takes exponentially more time as the input size increases. To understand different classes time complexity let's take example on them.

Constant Time Complexity O(1):
int findfirst(int a[])
{
return a[0];
}

The function takes constant time O(1) because it returns the element of the input array.

Linear Time Complexity O(n):
int findmax(int nums[])
{
int max=Integer.MIN_VALUE;
for(int i=0;i<n;i++)
{
    if(max<a[i])
    {
        max=a[i];
    }
return max;
}

The first line inside function takes constant time O(1).  The for loop takes O(n) time when size of the input is n. The if statement and max assignment operation take constant time O(1). The return statement also takes constant time O(1). Therefore the time complexity of the algorithm is O(n).

Quadratic time complexity O(n^2):

void bubbleSort(int[] numbers) {

    int n = numbers.length;

    for (int i = 0; i < n - 1; i++) {

        for (int j = 0; j < n - i - 1; j++) {

            if (numbers[j] > numbers[j + 1]) {

                int temp = numbers[j];

                numbers[j] = numbers[j + 1];

                numbers[j + 1] = temp;

            }

        }

    }

}

The first line takes constant time O(1). The outer for loop takes O(n) time where n is the length of the input array. The inner for loop takes O(n) time. The if statement and swap operation take constant time O(1). Therefore the overall time complexity of the bubbleSort function is O(n^2).

Logarithmic time complexity O(log n):

 public static int binarySearch(int[] numbers, int target) {

    int left = 0;

    int right = numbers.length - 1;

    while (left <= right) {

        int mid = left + (right - left) / 2;

        if (numbers[mid] == target) {

            return mid;

        } else if (numbers[mid] < target) {

            left = mid + 1;

        } else {

            right = mid - 1;

        }

    }

    return -1;

}

 The first two lines take constant time O(1). The while loop takes O(log n) time where n is the length of the input array. All other operations inside the loop take constant time O(1). Therefore, the overall time complexity of the binarySearch function is O(log n).

Let's take another example:



Linearithmic time complexity O(n log n):




Practice Problems:

To strengthen our knowledge further in time complexity, let's try several problems:








Hope you liked this explanation, for any doubt/feedback/improvements/corrections you can comment down in the comment section.

Popular posts from this blog

Pattern 6 | Java | MyCodingNetwork | Alok Tripathi (Code 8)

Problem Statement: Write a program to make a square and mark out its diagonals. Accept the length as input from the user and give output in the following manner: And ( In simple words, we have printed stars (*) on the boundary positions of the matrix and on the centre positions of the matrix we have printed blank space( ) )   THE CODE: Sample Output: In the above program, two int variables r to accept the length of square as input. On line 7, following statement is used to accept the input from the user: int r = sc . nextInt ();   For taking the input Scanner class has been used, more about Scanner class Algorithm: Two for loops are defined: ·         First for loop with counter variable i has initial value 1, conditional statement i less than or equal to r and an updating statement i++ . ·         Inside the first loop there is a second for loop, with counter variable j has ini...

Kadane's Algorithm | The-Algorithm-Drive | MyCodingNetwork

Kadane's Algorithm Kadane’s algorithm is used to find largest contagious subarray sum for a given array. It is one of the most common types of algorithms used to find the subarray with largest sum. The time complexity of this algorithm is O(N) .     Output :            Code Explanation: On line 4, there’s an  int  array variable a[ ], which is the array on which we have to perform our task. We have stored the value of the array, in variable l. cur_max,  is a temporary variable for traversing the array and storing positive sum occurring and update it after each iteration.  global_max , is a variable for storing the highest sum of subarray. ‘ start ’ variable stores the starting index of the desired subarray and ‘ end ’ variable stores the last index of that subarray, that is, contagious subarray with the highest sum. Working: Talking about the working of this algorithm, it uses one for loop and the entire operation can be perfo...

Pattern 4 | Java | MyCodingNetwork | Alok Tripathi (Code 6)

Problem Statement: Write a program to draw the following pattern where number of rows are decided by the user and given to the program as input:         *       * *     * * *   * * * * * * * * * * * * * * * (Take a variable n which takes the number of rows as input from the user, For above example, n=6) OUTPUT: The above program is the extension of the previous program (Pattern #3). This program asks the user to input the number of rows that it wants in the program. For accepting the input, the program has Scanner class which has been extracted from the package java.util . In this program, we will learn how to receive data from the user. If you remember in three previous patterns, the program itself had the input of number of rows where n=8, but now the user will tell the program how many rows are to be added.   Simplification 1.     In Line 1, the java.util  package has been imported, to use the Scanner cl...