5.19
1.最开始用的两个for循环,不用想,一定超时了。
2.又现学了归并排序,但是好像网上只有二路归并排序,我还没有找到其他的方法,有机会也是要学习一下的。
3.将分治的思想用在这道题中,就是要弄清楚,当 左边的数 大于右边的数的时候,会产生几对逆序对。这一点写在了代码的注释中,要再好好消化一下。最初就是没有搞明白这个问题,一直出错。
public class Solution {
/**
* @param A an array
* @return total of reverse pairs
*/
public long count = 0;
public long reversePairs(int[] A) {
// Write your code here
int length = A.length;
if(length <= 1){
return 0;
}
// 就知道这样的双循环的n^2的复杂度的方法是一定会超时的,我是服气的呢
/*
for(int i = 0; i < length -1; i++){
for(int j = i; j < length; j++){
if(A[i] > A[j]){
count ++;
}
}
}
*/
// 采用归并排序的方法。
sort(A,0,length -1);
//System.out.println(Arrays.toString(A));
return count;
}
public void sort(int[] A,int low,int height){
if(low >= height){
return;
}
int mid = (low + height)/2;
sort(A,low,mid);
sort(A,mid+1,height);
merge(A,low,mid,height);
//System.out.println(Arrays.toString(A));
}
public void merge(int A[],int low,int mid ,int height){
/* 左边的有 mid - low + 1 个数,右边有 height - mid 个数
当出现A[left_flag] > A[right_flag] 的时候,表示,A[left_flag] ~ A[mid] 都大于,因此会产生 mid - left_flag + 1 对逆序列对。
******/
int[] tmpArr = new int[A.length];
int tmpArr_flag = low;
int left_flag = low;
int right_flag = mid + 1;
while(left_flag <= mid && right_flag <= height){
if(A[left_flag] > A[right_flag]){
tmpArr[tmpArr_flag] = A[right_flag];
tmpArr_flag ++;
count = count + (mid - left_flag + 1);
right_flag ++;
}
else{
tmpArr[tmpArr_flag] = A[left_flag];
left_flag ++;
tmpArr_flag ++;
}
}
while(left_flag <= mid){
tmpArr[tmpArr_flag] = A[left_flag];
tmpArr_flag ++;
left_flag ++;
}
while(right_flag <= height){
tmpArr[tmpArr_flag] = A[right_flag];
tmpArr_flag ++;
right_flag ++;
}
tmpArr_flag = low;
while(tmpArr_flag <= height){
A[tmpArr_flag] = tmpArr[tmpArr_flag];
tmpArr_flag++;
}
//System.out.println(Arrays.toString(A));
}
}