在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4]
输出: 5
思路:
使用归并排序的思想,因为在归并排序中,他的过程是先拆分,在合并。
在拆分的时候,我们可以通过看左区间大于右区间的某一个数,那个这个左区间右边的数都大于它。通过这个关系可以轻松的解决逆数对的问题。
时间复杂度:
Nlogn
class Solution {
int []temp;
public int reversePairs(int[] nums) {
//需要一个临时数组来保存这个区间里面的数
temp=new int[nums.length];
//归并排序解决问题
return mergesort(nums,0,nums.length-1);
}
public int mergesort(int []nums,int l,int r){
//终止条件
if(l>=r){
return 0;
}
//拆分:
int mid=l+(r-l)/2;
int res=mergesort(nums,l,mid)+mergesort(nums,mid+1,r);
//合并
//将nums l-r区间里面的数 保存到临时的数组中,便于之后的排序
for(int i=l;i<=r;i++){
temp[i]=nums[i];
}
//i 和j分别是左右区间的指针
int i=l;
int j=mid+1;
for(int k=l;k<=r;k++){
if(i==mid+1){
//代表 右边区间的数还没有存完
nums[k]=temp[j++];
}else if(j==r+1||temp[i]<=temp[j]){
nums[k]=temp[i++];
}else if(temp[i]>temp[j]){
nums[k]=temp[j++];
res+=mid-i+1;
}
}
return res;
}
}