Count of Smaller Numbers After Self

You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].

Example:

Input: [5,2,6,1]
Output: [2,1,1,0] 
Explanation:
To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.
class Solution {
    static class Pair {
        int val, i;

        Pair(int val, int index) {
            this.val = val;
            this.i = index;
        }
    }

    List<Integer> ans;

    public List<Integer> countSmaller(int[] nums) {
        // Creating answer array
        ans = new ArrayList<>();
        Pair[] arr = new Pair[nums.length];
        for (int i = 0; i < arr.length; i++) {
            ans.add(0);
            arr[i] = new Pair(nums[i], i);
        }
        mergeSort(arr, 0, nums.length - 1);
        return ans;
    }

    public void mergeSort(Pair[] arr, int start, int end) {
        if (start >= end)
            return;
        int mid = start + (end - start) / 2;
        mergeSort(arr, start, mid);
        mergeSort(arr, mid + 1, end);
        merge(arr, start, end);
    }

    public void merge(Pair[] arr, int start, int end) {
        int mid = start + (end - start) / 2;
        Pair[] temp = new Pair[end - start + 1];
        int index = 0, pointer1 = start, pointer2 = mid + 1;
        int limit = mid + 1;
        while (pointer1 <= mid) {
            // For every element in the left part, we are finding count of 
            // elements in right part < element
            while (limit <= end && arr[limit].val < arr[pointer1].val)
                limit++;
            ans.set(arr[pointer1].i, ans.get(arr[pointer1].i) + limit - (mid + 1));
            // Merge process
            while (pointer2 <= end && arr[pointer2].val < arr[pointer1].val)
                temp[index++] = arr[pointer2++];
            temp[index++] = arr[pointer1++];
        }
        while (pointer2 <= end)
            temp[index++] = arr[pointer2++];
        for (int i = start; i <= end; i++)
            arr[i] = temp[i - start];
    }
}

Last updated