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