Leetcode 315. Count of Smaller Numbers After Self
题目链接: Count of Smaller Numbers After Self
难度:Hard
题目大意:
给出一个数组,求各个元素的右边有多少个比自己小的元素。
思路:
参考高赞回答1和高赞回答2,求解过程实际上是模拟归并排序的过程。
代码
class Solution {
int[] count;
public List<Integer> countSmaller(int[] nums) {
int n=nums.length;
count=new int[n];
int[] indexes=new int[n];
for(int i=0;i<n;i++){
indexes[i]=i;
}
mergeSort(nums,indexes,0,n-1);
List<Integer> res=new ArrayList<>();
for(int i:count){
res.add(i);
}
return res;
}
public void mergeSort(int[] nums,int[] indexes,int l,int r){
if(l>=r){
return;
}
int mid=l+(r-l)/2;
mergeSort(nums,indexes,l,mid);
mergeSort(nums,indexes,mid+1,r);
merge(nums,indexes,l,r);
}
public void merge(int[] nums,int[] indexes,int l,int r){
int mid=l+(r-l)/2;
int i=l,j=mid+1;//左右部分的起始下标
int rightCount=0;//统计右半部分有多少个元素比左半部分当前遍历到的元素小
int[] sorted=new int[r-l+1];//对数组元素,但是不记录元素,而是记录元素的下标
int k=0;
while(i<=mid&&j<=r){
if(nums[indexes[j]]<nums[indexes[i]]){
rightCount++;
sorted[k++]=indexes[j];
j++;
}
else{
count[indexes[i]]+=rightCount;
sorted[k++]=indexes[i];
i++;
}
}
while(i<=mid){
count[indexes[i]]+=rightCount;
sorted[k++]=indexes[i];
i++;
}
while(j<=r){
sorted[k++]=indexes[j];
j++;
}
for(k=l;k<=r;k++){
indexes[k]=sorted[k-l];
}
}
}