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 {
private:
vector<pair<int, int> > x;
vector<int> ans;
public:
vector<int> countSmaller(vector<int>& nums) {
if(!nums.size()) return vector<int>();
for(int i=0; i<nums.size(); i++)
x.push_back(make_pair(nums[i],i));
ans = vector<int>(x.size(), 0);
InverseCore(nums, 0, nums.size()-1);
return ans;
}
void InverseCore(vector<int> &nums, int start, int end)
{
if(start>=end) return;
int mid = start + (end - start)/2;
InverseCore(nums, start, mid);
InverseCore(nums, mid+1, end);
merge_sort(nums, start, mid, mid+1, end);
}
void merge_sort(vector<int> &num, int start1, int end1, int start2, int end2)
{
int p = start1;
int q = start2;
vector<pair<int, int> > tmp;
while(p<=end1&&q<=end2)
{
if (x[p].first <= x[q].first) {
ans[x[p].second] += q - start2;
tmp.push_back(x[p++]);
} else {
tmp.push_back(x[q++]);
}
}
while (p <= end1) {
ans[x[p].second] += q - start2;
tmp.push_back(x[p++]);
}
while (q <= end2) tmp.push_back(x[q++]);
for (int i = start1; i<= end2; i++) x[i] = tmp[i - start1];
}
};