class Solution {
public List<Integer> countSmaller(int[] nums) {
List<Integer> result = new ArrayList<>();
if(nums==null)
return result;
//
//索引映射, 原始索引与新索引的对应关系, 新索引会改变
int n = nums.length;
int[] indexMap = new int[n];
for(int i=0; i<n; i++){
indexMap[i] = i;
}
//临时结果
int[] res = new int[n];
//对indexMap进行归并排序
mergesort(res, nums, indexMap, 0, n-1);
//把res的结果给result
for(int a : res){
result.add(a);
}
return result;
}
public void mergesort(int[] res, int[] nums, int[] indexMap, int left, int right){
//会有left>right的情况吗? 有, 当nums.length==0时, left=0, right=-1, 所以要么在input check中检查length, 要么把这个if条件改成left>=right
if(left>=right)
return;
int mid = left + ((right-left)>>1);
mergesort(res, nums, indexMap, left, mid);
mergesort(res, nums, indexMap, mid+1, right);
merge(res,nums,indexMap,left,mid,right);
}
public void merge(int[] res, int[] nums, int[] indexMap, int left, int mid, int right){
int[] help = new int[right-left+1];
int p1 = left, p2 = mid+1, p=0;
int count = 0;
while(p1<=mid && p2<=right){
//如果右部分的小
if(nums[indexMap[p1]] > nums[indexMap[p2]]){
help[p++] = indexMap[p2++];
count++;
}
//如果左部分的小
else{
help[p++] = indexMap[p1];
res[indexMap[p1++]] += count;
}
}
//如果左部分还有没处理的
while(p1<=mid){
help[p++] = indexMap[p1];
res[indexMap[p1++]] += count;
}
//如果右部分还有没处理的
while(p2<=right){
help[p++] = indexMap[p2++];
//此时不需要再更新count了
}
//将help的结果更新给indexMap
for(int i=0; i<right-left+1; i++){
indexMap[left+i] = help[i];
}
}
}