给定一个数组,需要求出数组的逆序对的个数:
归并排序包含以下三个步骤:
- **分解:**待排序的区间为[l,r],令mid=(l+r)>>1;我们把[l,r]分解为[l,mid]和[mid+1,r];
- **解决:**使用归并排序递归的排序两个子序列
- **合并:**把两个已经排好序的子序列合并起来
而求逆序对和归并排序的关系就是[并]的过程,在合并的过程中,如果找到了左指针指示的数比右指针指示的数大的情况,那么就可以算出他对逆序对的贡献度。
int ans=0;
vector<int>new_nums;
void msort(vector<int>& nums,int start,int end){
if(start>=end) return ;
int mid=(start+end)/2;
msort(nums,start,mid); //分解
msort(nums,mid+1,end);
int i=start;
int j=mid+1;
int k=start;
while(i<=mid&&j<=end){ //解决
if(nums[i]<=nums[j]) new_nums[k++]=nums[i++]; //合并
else{
ans+=mid-i+1;
new_nums[k++]=nums[j++];
}
}
while(i<=mid) new_nums[k++]=nums[i++];
while(j<=end) new_nums[k++]=nums[j++];
copy(new_nums.begin()+start,new_nums.begin()+end+1,nums.begin()+start); //拷贝
}
int reversePairs(vector<int>& nums) {
int n=nums.size();
new_nums.resize(n,0);
msort(nums,0,n-1);
return ans;
}