剑指Offer35:数组中的逆序对(Java)
***参考 1. 新竹六月的博客:https://www.cnblogs.com/coffy/p/5896541.html
2. 努力学习的宵夜的博客:https://www.cnblogs.com/xiaoyebula/p/12045554.html***
解题思路:
\(\color{#fa163f}{逆序对的总数=左边数组中的逆序对的数量+右边数组中逆序对的数量+左右结合成新的顺序数组时中出现的逆序对的数量;}\)
采用分治的思想,利用归并排序的方法计算数组中的逆序对。与归并排序不同的是从右往左遍历,这样计算逆序对方便。
还有就是计算过中大于1000000007的结果和最终结果要取模。
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
java代码:
public class Solution {
public static int InversePairs(int[] array){
if(array==null||array.length==0){
return 0;
}
return Inversepairs(array,0,array.length-1);
}
public static int Inversepairs(int []arr,int left,int right){
if(left>=right){
return 0;
}
int mid =(left+right)/2;
int leftcount=Inversepairs(arr,left,mid);
int rightcount=Inversepairs(arr,mid+1,right);
int count=InversePairsCore(arr,left,right,mid);
return (leftcount+rightcount+count)%1000000007;
}
private static int InversePairsCore(int[] arr, int left, int right, int mid) {
int i,j,k;
int [] temp=new int[right-left+1];
i=mid;
j=right;
k=temp.length-1;
int sum=0;
while(i>=left&&j>=mid+1){
if(arr[i]>arr[j]){
temp[k--]=arr[i--];
sum+=j-mid;
if(sum>=1000000007)//数值过大求余
{
sum%=1000000007;
}
}
else {
temp[k--]=arr[j--];
}
}
while(i>=left){
temp[k--]=arr[i--];
}
while(j>mid){
temp[k--]=arr[j--];
}
i=left;
for(k=0;k<temp.length;k++){
arr[i++]=temp[k];
}
return sum;
}
}