Posts Count Inversions (geeksforgeeks - SDE Sheet)
Post
Cancel

Count Inversions (geeksforgeeks - SDE Sheet)

PROBLEM DESCRIPTION

Given an array of integers. Find the Inversion Count in the array. Two array elements arr[i] and arr[j] form an inversion if arr[i] > arr[j] and i < j.

Inversion Count: For an array, inversion count indicates how far (or close) the array is from being sorted. If the array is already sorted then the inversion count is 0. If an array is sorted in the reverse order then the inversion count is the maximum.

geeksforgeeks

SOLUTION

Good Explaination - takeUForward

The merge sort code has been taken from here: geeksforgeeks

Let’s say, we want to count such a pair between two arrays arr1 and arr2 and both of them are in their sorted order.

We can start iterating from left to right on both the arrays. Suppose we get an index i from arr1 and index j in arr2 such that arr1[i] > arr2[j], then we can surely say that all elements at index >= i in arr1 will also be larger than arr2[j] since the elements are in sorted order. So, we can directly add size of arr1 - i to the number of pairs. We can then continue to look at other elements in arr2.

This step actually happens during merge sort, while merging two already sorted arrays. We can use this to our advantage. In this merge function, whenever we get into the step where left element is larger than right element, we increase the number of pairs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
class Solution {

    // arr[]: Input Array
    // N : Size of the Array arr[]
    // Function to count inversions in the array.
    static long inversionCount(long arr[], int n) {

        // reset, otherwise it will fail for rest test cases it seems
        count = 0;

        sort(arr, 0, n-1);
        return count;
    }

    static long count = 0;

    // standard merge sort
    static void sort(long arr[], int l, int r)
    {
        if (l < r) {

            // Find the middle point
            int m = l + (r - l) / 2;

            // Sort first and second halves
            sort(arr, l, m);
            sort(arr, m + 1, r);

            // Merge the sorted halves
            merge(arr, l, m, r);
        }
    }


    // standard merge in merge sort
    static void merge(long arr[], int l, int m, int r)
    {
        // Find sizes of two subarrays to be merged
        int n1 = m - l + 1;
        int n2 = r - m;

        // Create temp arrays
        long L[] = new long[n1];
        long R[] = new long[n2];

        // Copy data to temp arrays
        for (int i = 0; i < n1; ++i)
            L[i] = arr[l + i];
        for (int j = 0; j < n2; ++j)
            R[j] = arr[m + 1 + j];

        // Merge the temp arrays

        // Initial indices of first and second subarrays
        int i = 0, j = 0;

        // Initial index of merged subarray array
        int k = l;

        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) {
                arr[k] = L[i];
                i++;
            }
            else {

                // THIS IS THE MAIN LOGIC
                // If current left is greater and current right
                // and we know that both the sub arrays are sorted
                // all the elements towards the right on first/left subarray will also be larger
                // so, they will add to the total number of pairs
                count += (n1 - i);

                arr[k] = R[j];
                j++;
            }
            k++;
        }

        // Copy remaining elements of L[] if any
        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }

        // Copy remaining elements of R[] if any
        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }

    }


}

AVOID GLOBAL COUNT VARIABLE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
class Solution {

    // arr[]: Input Array
    // N : Size of the Array arr[]
    // Function to count inversions in the array.
    static long inversionCount(long arr[], int n) {
        return sort(arr, 0, n-1);
    }

    static long sort(long arr[], int l, int r)
    {
        long count = 0;

        if (l < r) {

            // Find the middle point
            int m = l + (r - l) / 2;

            // Sort first and second halves
            count += sort(arr, l, m);
            count += sort(arr, m + 1, r);

            // Merge the sorted halves
            count += merge(arr, l, m, r);
        }

        return count;
    }



    static long merge(long arr[], int l, int m, int r)
    {

        long count = 0;

        // Find sizes of two subarrays to be merged
        int n1 = m - l + 1;
        int n2 = r - m;

        // Create temp arrays
        long L[] = new long[n1];
        long R[] = new long[n2];

        // Copy data to temp arrays
        for (int i = 0; i < n1; ++i)
            L[i] = arr[l + i];
        for (int j = 0; j < n2; ++j)
            R[j] = arr[m + 1 + j];

        // Merge the temp arrays

        // Initial indices of first and second subarrays
        int i = 0, j = 0;

        // Initial index of merged subarray array
        int k = l;

        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) {
                arr[k] = L[i];
                i++;
            }
            else {

                count += (n1 - i);

                arr[k] = R[j];
                j++;
            }
            k++;
        }

        // Copy remaining elements of L[] if any
        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }

        // Copy remaining elements of R[] if any
        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }

        return count;

    }


}
This post is licensed under CC BY 4.0 by the author.