Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com

Count Inversions - ll

Moderate
0/80
Average time to solve is 50m
profile
Contributed by
36 upvotes
Asked in companies
AmazonMicrosoftAdobe

Problem statement

Given a Singly Linked List of integers, return its inversion count. The inversion count of a linked list is a measure of how far it is from being sorted.

Two nodes 'N1' and 'N2' form an inversion if the value of 'N1' is greater than the value of 'N2' and 'N1' appears before 'N2' in the linked list.

Detailed explanation ( Input/output format, Notes, Images )
Input Format:
The first and the only line of the input contains the elements of the singly linked list separated by a single space and terminated by -1. Hence, -1 would not be a list element.
Output Format:
Print a single integer denoting the inversion count of the given linked list.
Note:
You don't need to print the output, it has already been taken care of. Just implement the given function. 
Constraints:
0 <= L <= 10^5
-10^9 <= data <= 10^9 and data != -1

Where L is the number of nodes in the linked list and 'data' is the node value of the linked list.

Time Limit: 1 sec
Sample Input 1:
3 2 1 5 4 -1
Sample Output 1:
4
Explanation of the Sample Input 1:
For the given linked list, there are 4 inversions: (3, 2), (3, 1), (2, 1) and (5, 4). Thus, the inversion count of the given linked list is 4.
Sample Input 2:
0 6 8 7 -1
Sample Output 2:
1
Explanation of the Sample Output 2:
For the given linked list, there is only 1 inversion: (8, 7). Thus, the inversion count of the given linked list is 1.
Hint

Try to find the number of nodes that form an inversion pair for each node in the linked list.

Approaches (2)
Brute Force Approach

Initially, we declare a counter ‘INVERSIONCNT’ and initialize it with ‘0’, Where  â€˜INVERSIONCNT’ maintains the count of inversions in the given linked list. Also, Declare a pointer ‘CUR’, initialized to the ‘HEAD’ of the linked list, to traverse the entire list, and also a pointer ‘TEMP’ to traverse the part of the linked list after ‘CUR’. 

 

For every node pointed by the ‘CUR’, we use the ‘TEMP’ pointer to start traversal from the node next to the ‘CUR’. We compare the values of the nodes pointed by the pointer ‘TEMP’ and the ‘CUR’ pointer and if the value pointed by ‘CUR’ is greater than that pointed by ‘TEMP’, then the 2 nodes form an inversion pair and we increment the counter ‘INVERSIONCNT’ by ‘1’.

 

We repeat the entire process till ‘CUR’ reaches the end of the list.

Time Complexity

O(L^2), where ‘L’ is the number of nodes in the linked list.

 

Since we are iterating through the linked list once in O(L) time and there are ‘L’ nodes for each iteration which takes O(L) time and thus the overall time complexity will be O(L * L) = O(L^2).

Space Complexity

O(1).

 

Since we are using constant additional space and thus the space complexity will be O(1).

Code Solution
(100% EXP penalty)
Count Inversions - ll
All tags
Sort by
Search icon

Interview problems

Python Solution | Count Inversions - II | All Test cases passed

# Following is the class structure of the Node class:   

class Node:

    def __init__(self, data):

        self.data = data

        self.next = None

 

# Function to convert the linked list into an array

def linked_list_to_array(head):

    arr = []

    current = head

    while current is not None and current.data != -1:

        arr.append(current.data)

        current = current.next

    return arr

 

# Merge function to count inversions

def merge_and_count(arr, temp_arr, left, mid, right):

    i = left    # Starting index for left subarray

    j = mid + 1 # Starting index for right subarray

    k = left    # Starting index for sorted subarray

    inv_count = 0

 

    while i <= mid and j <= right:

        if arr[i] <= arr[j]:

            temp_arr[k] = arr[i]

            i += 1

        else:

            # There are mid - i inversions because all elements in the left

            # subarray (arr[i], arr[i+1], ..., arr[mid]) are greater than arr[j]

            temp_arr[k] = arr[j]

            inv_count += (mid - i + 1)

            j += 1

        k += 1

 

    # Copy the remaining elements of left subarray, if any

    while i <= mid:

        temp_arr[k] = arr[i]

        i += 1

        k += 1

 

    # Copy the remaining elements of right subarray, if any

    while j <= right:

        temp_arr[k] = arr[j]

        j += 1

        k += 1

 

    # Copy the sorted subarray into the original array

    for i in range(left, right + 1):

        arr[i] = temp_arr[i]

 

    return inv_count

 

# Function to implement merge sort and count inversions

def merge_sort_and_count(arr, temp_arr, left, right):

    inv_count = 0

    if left < right:

        mid = (left + right) // 2

 

        inv_count += merge_sort_and_count(arr, temp_arr, left, mid)

        inv_count += merge_sort_and_count(arr, temp_arr, mid + 1, right)

 

        inv_count += merge_and_count(arr, temp_arr, left, mid, right)

 

    return inv_count

 

def calculateInversionCnt(head):

    # Step 1: Convert the linked list to an array

    arr = linked_list_to_array(head)

    

    # Step 2: Create a temporary array for merge sort

    n = len(arr)

    temp_arr = [0] * n

    

    # Step 3: Perform merge sort and count inversions

    return merge_sort_and_count(arr, temp_arr, 0, n - 1)

 

# Helper function to create a linked list from a list of values

def create_linked_list(elements):

    dummy = Node(0)

    current = dummy

    for elem in elements:

        current.next = Node(elem)

        current = current.next

    return dummy.next

 

2 views
0 replies
0 upvotes

Interview problems

Discussion thread on Interview Problem | Count Inversions - ll

Hey everyone, creating this thread to discuss the interview problem - Count Inversions - ll.

 

Practise this interview question on Coding Ninjas Studio (hyperlinked with the following link): Count Inversions - ll

 

691 views
5 replies
1 upvote
Full screen
Console