题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
示例1
输入
1,2,3,4,5,6,7,0
输出
7
源代码:
解法一:
public class Solution {
public int InversePairs(int [] array) {
int len=array.length;
int []copy=new int[len];
for(int i=0;i<len;i++)
copy[i]=array[i];
int cnt=getcount(array,copy,0,len-1);
return cnt;
}
int getcount(int []data,int []copy,int low,int high ){
if(low==high) return 0;
int mid=(low+high)>>1;
int leftcnt=getcount(data, copy, low, mid )%1000000007;
int rightcnt=getcount(data,copy, mid+1, high )%1000000007;
int cnt=0;
int i=mid,j=high;
int pos=high;
while(i>=low&&j>=mid+1){//从两个字数组的最后一位开始,因为数组是按照从小到大的顺序递增排列的
if(data[i]>data[j]){//如果前面元数组的最后一个元素比后面数组的最后一个元素要大的话,则说明说明前面数组的最后一个元素比第二个数组的所有元素都要大
copy[pos--]=data[i--];//把第一个数组的元素复制到临时数组中,并且指针减1
cnt+=j-mid;//
cnt=cnt%1000000007;
}else{//data[i]<data[j]
//如果前面数组的最后一个元素比后面数组的最后一个元素要小的话,则说明后面数组的所有元素都要比第一个数组的元素小,指针各自减1
copy[pos--]=data[j--];
}
}
for(;i>=low;i--)
copy[pos--]=data[i];
for(;j>=mid+1;j--)
copy[pos--]=data[j];
for(i=low;i<=high;i++)
data[i]=copy[i];//把排好序的元素从临时数组拷贝到原数组中
return (cnt+leftcnt+rightcnt)%1000000007;
}
}
解法二://没有通过,没找到原因
public class Solution {
int cnt=0;
public int InversePairs(int [] array) {
int len=array.length;
mergesort(array,0,len-1);
return cnt;
}
void mergesort(int[] arr,int start,int end){
if(start>=end) return;
int mid=(start+end)>>1;
mergesort(arr, start, mid);
mergesort(arr, mid+1, end);
merge(arr,start,mid,end);
}
void merge(int[] arr,int start,int mid,int end){
int tmp[]=new int[end-start+1];
int i=mid,j=end;
int pos=end;
while(i>=start&&j>=mid+1){
if(arr[i]>arr[j]){
tmp[pos--]=arr[i--];
cnt+=j-mid;
cnt=cnt%1000000007;
}else{//arr[i] < arr[j]
tmp[pos--]=arr[j--];
}
}
for(;i>=start;i--){
tmp[pos--]=arr[i];
}
for(;j>=mid+1;j--){
tmp[pos--]=arr[j];
}
for(i=start;i<=end;i++)
arr[i]=tmp[i];
}
}
解法三:
public class Solution {
int cnt;
public int InversePairs(int[] array) {
cnt = 0;
if (array != null)
mergeSortUp2Down(array, 0, array.length - 1);
return cnt;
}
/*
* 归并排序(从上往下)
*/
public void mergeSortUp2Down(int[] a, int start, int end) {
if (start >= end)
return;
int mid = (start + end) >> 1;
mergeSortUp2Down(a, start, mid);
mergeSortUp2Down(a, mid + 1, end);
merge(a, start, mid, end);
}
/*
* 将一个数组中的两个相邻有序区间合并成一个
*/
public void merge(int[] a, int start, int mid, int end) {
int[] tmp = new int[end - start + 1];
int i = start, j = mid + 1, k = 0;
while (i <= mid && j <= end) {
if (a[i] <= a[j])
tmp[k++] = a[i++];
else {
tmp[k++] = a[j++];
cnt += mid - i + 1; // core code, calculate InversePairs............
cnt=cnt%1000000007;
}
}
while (i <= mid)
tmp[k++] = a[i++];
while (j <= end)
tmp[k++] = a[j++];
for (k = 0; k < tmp.length; k++)
a[start + k] = tmp[k];
}
}