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]
.
Test Cases
Example 1:
Input: nums = [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.
Example 2:
Input: nums = [-1,-1]
Output: [0,0]
Solution
class Solution {
public:
void merge(vector<int> &count, vector<pair<int, int> > &v, int left, int mid, int right) {
vector<pair<int, int> > tmp(right-left+1);
int i = left;
int j = mid+1;
int k = 0;
while (i <= mid && j <= right) {
if (v[i].first <= v[j].first) {
tmp[k++] = v[j++];
}
else {
count[v[i].second] += right - j + 1;
tmp[k++] = v[i++];
}
}
while (i <= mid) {
tmp[k++] = v[i++];
}
while (j <= right) {
tmp[k++] = v[j++];
}
for (int i = left; i <= right; i++)
v[i] = tmp[i-left];
}
void mergeSort(vector<int> &count, vector<pair<int, int> > &v, int left, int right) {
if (left >= right)
return;
int mid = left + (right-left)/2;
mergeSort(count, v, left, mid);
mergeSort(count, v, mid+1, right);
merge(count, v, left, mid, right);
}
vector<int> countSmaller(vector<int>& nums) {
int N = nums.size();
vector<pair<int, int> > v(N);
for (int i = 0; i < N; i++)
v[i] = make_pair(nums[i], i);
vector<int> count(N, 0);
mergeSort(count, v, 0, N-1);
return count;
}
};
class Solution {
public List<Integer> countSmaller(int[] nums) {
int n = nums.length;
Pair[] pairs = new Pair[n];
for(int i=0; i<n; i++) {
pairs[i] = new Pair(nums[i], i);
}
int[] count = new int[n];
mergeSort(count, pairs, 0, n-1);
List<Integer> result = new ArrayList<>();
for(int c: count) result.add(c);
return result;
}
private void mergeSort(int[] count, Pair[] pairs, int left, int right) {
if (left >= right) return;
int mid = left + (right-left)/2;
mergeSort(count, pairs, left, mid);
mergeSort(count, pairs, mid+1, right);
merge(count, pairs, left, mid, right);
}
private void merge(int[] count, Pair[] pairs, int left, int mid, int right) {
Pair[] temp = new Pair[right-left+1];
int i=left, j=mid+1, k=0;
while(i <= mid && j<= right) {
if (pairs[i].val <= pairs[j].val) {
temp[k++] = pairs[j++];
} else {
count[pairs[i].pos] += right - j + 1;
temp[k++] = pairs[i++];
}
}
while(i <= mid) {
temp[k++] = pairs[i++];
}
while(j <= right) {
temp[k++] = pairs[j++];
}
for(i=left; i<= right; i++) {
pairs[i] = temp[i-left];
}
}
}
class Pair {
int val;
int pos;
public Pair(int val, int pos) {
this.val = val;
this.pos = pos;
}
}