题目:
给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。
来源:力扣(LeetCode)
利用归并排序的思想。
每当右侧元素放入临时数组时,tmp。
而当左侧元素放入临时数组时,在相应的counter位置处加上tmp。
为了保证元素的顺序,我们用一个索引数组来进行归并。
详细过程参考:https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/solution/gui-bing-pai-xu-suo-yin-shu-zu-python-dai-ma-java-/
private int[] temp;
private int[] index;
private int[] counter;
public List<Integer> countSmaller(int[] nums) {
List<Integer> res = new ArrayList<>();
if(nums.length == 0)
return res;
temp = new int[nums.length];
index = new int[nums.length];
for(int i = 0;i<nums.length;i++)
index[i] = i;
counter = new int[nums.length];
sort(nums,0,nums.length-1);
for(int x:counter)
res.add(x);
return res;
}
public void sort(int[] nums,int lo,int hi) {
if(lo == hi) {
return;
}
int mid = (lo+hi)/2;
sort(nums,lo,mid);
sort(nums,mid+1,hi);
if(nums[index[mid]]>nums[index[mid+1]]) {
merge(nums,lo,mid,hi);
}
}
public void merge(int[] nums,int lo,int mid,int hi) {
for(int p = lo;p<=hi;p++)
temp[p] = index[p];
int i = lo;
int j = mid+1;
int k = lo;
int tmp = 0;
while(i<=mid&&j<=hi) {
if(nums[temp[i]]<=nums[temp[j]]) {
index[k] = temp[i];
counter[index[k]] +=tmp;
k++;
i++;
}
else {
index[k] = temp[j];
k++;
j++;
tmp++;
}
}
while(i<=mid) {
index[k] = temp[i];
counter[index[k]] +=tmp;
k++;
i++;
}
while(j<=hi) {
index[k] = temp[j];
k++;
j++;
}
}