在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4]
输出: 5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
最近的题都超出知识储备了,学习记录一下吧,官方题解
解释的特别详细
class Solution {
public int reversePairs(int[] nums) {
int len=nums.length;
if(len<2) return 0;
int[] copy = new int[len];
for(int i=0;i<len;i++){
copy[i] = nums[i];
}
int[] tem = new int[len];
//归并排序
return reversePairs(copy,0,len-1,tem);
}
private int reversePairs(int[] nums,int left,int right,int[] tem){
if(left==right) return 0;
int mid = left+(right-left)/2;
int leftPairs = reversePairs(nums,left,mid,tem);
int rightPairs = reversePairs(nums,mid+1,right,tem);
if(nums[mid]<nums[mid+1]){
return leftPairs+rightPairs;
}
int crossPairs = mergeAndCount(nums,left,mid,right,tem);
return leftPairs+rightPairs+crossPairs;
}
private int mergeAndCount(int[] nums,int left,int mid,int right,int[] tem){
int count = 0;
for(int i=left;i<=right;i++){//复制数组
tem[i]=nums[i];
}
int i=left,j=mid+1;
for(int k=left;k<=right;k++){
if(i==mid+1){
nums[k]=tem[j];
j++;
}else if(j==right+1){
nums[k]=tem[i];
i++;
}else if(tem[i]<=tem[j]){
nums[k]=tem[i];
i++;
}else{
nums[k]=tem[j];
j++;
count+=mid-i+1;
}
}
return count;
}
}