Striver-SDE-Sheet

Repository containing solution for #SdeSheetChallenge by striver

View the Project on GitHub

Count Inversions

Given an array of integers. Find the Inversion Count in the array.

Inversion Count: For an array, inversion count indicates how far (or close) the array is from being sorted. If 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. Formally, two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j.

Brute force (TLE)

typedef long long ll;
ll inversionCount(ll arr[], ll N)
{
    ll cnt = 0;
    for (ll i = 0; i < N; i++) {
        for (ll j = i + 1; j < N; j++) {
            if (arr[i] > arr[j])
                cnt++;
        }
    }
    return cnt;
}

Using Merge Sort (AC)

Code

typedef long long ll;

ll merge(ll arr[], ll temp[], ll left, ll mid, ll right)
{
    ll i, j, k;
    ll inv_count = 0;

    i = left; /* i is index for left subarray*/
    j = mid;  /* j is index for right subarray*/
    k = left; /* k is index for resultant merged subarray*/

    while ((i < mid) && (j <= right)) { // this is merge part
        if (arr[i] <= arr[j]) {
            temp[k++] = arr[i++];
        } else {
            temp[k++] = arr[j++];
            inv_count += (mid - i);
        }
    }

    // Copy the remaining elements of left subarray
    while (i < mid)
        temp[k++] = arr[i++];

    // Copy the remaining elements of right subarray
    while (j <= right)
        temp[k++] = arr[j++];

    // Copy back the merged elements to original array
    for (i = left; i <= right; i++)
        arr[i] = temp[i];

    return inv_count;
}

ll _mergeSort(ll arr[], ll temp[], ll left, ll right)
{
    ll mid, inv_count = 0;
    if (right > left) {
        // Divide the array into two parts and call
        mid = (right + left) / 2;

        // Inversion count = inversions(leftHalf) + Inversion(rightHalf)
        inv_count += _mergeSort(arr, temp, left, mid);
        inv_count += _mergeSort(arr, temp, mid + 1, right);

        // Merge the two parts
        inv_count += merge(arr, temp, left, mid + 1, right);
    }
    return inv_count;
}

ll inversionCount(ll arr[], ll N)
{
    ll* temp = (ll*)malloc(sizeof(ll) * N); // temporary array
    return _mergeSort(arr, temp, 0, N - 1);
}