3.第三次做:归并排序思路+求余
知道这道题考的不是大数之后就没太注意,只是在最后mod了一下,加上两处中间计算结果的求余之后就可以通过了。
res += mergeSort(array, start, mid); res += mergeSort(array, mid+1, end); res += merge(array, start, mid, end); res = res % 1000000007;
count += mid-c1+1; count = count % 1000000007;
2.第二次做:归并排序思路
(1)归并排序先将数组不断二等分成左右两边各1个元素, 比较这两个元素判断是否构成逆序对, 并将这个两个元素合并成一个有序的数组, 归并后的数组因为是递增排序的,所以不再包含逆序对。
(2)接着比较长度为2的两个数组, 首先这两个数组内部没有逆序对了, 所以只有在合并两个数组的过程中包含逆序对。、
代码:只是在归并排序的基础代码上加入了一行count的计算,提交只能通过50%的测试样例。进一步分析一下还有哪个细节没有思考到位。
public class Solution {
public int InversePairs(int[] array){
int res = mergeSort(array, 0, array.length-1);
return res%1000000007;
}
public int mergeSort(int[] array, int start, int end){
int res = 0;
if(start<end){
int mid = (start+end)/2;
res += mergeSort(array, start, mid);
res += mergeSort(array, mid+1, end);
res += merge(array, start, mid, end);
}
return res;
}
public int merge(int[] array, int start, int mid, int end){
int[] newarray = new int[end-start+1];
int c1 = start, c2 = mid+1;
int pos = 0, count = 0;
while(c1<=mid && c2<=end){
if(array[c1]<array[c2]){
newarray[pos++] = array[c1++];
}
else{
//说明c2比前半部分剩下的元素都小
count += mid-c1+1;
newarray[pos++] = array[c2++];
}
}
//处理剩余段
while(c1<=mid)
newarray[pos++] = array[c1++];
while(c2<=end)
newarray[pos++] = array[c2++];
//复制回原数组
for(int i = start; i<=end; i++)
array[i] = newarray[i-start];
return count;
}
}1.第一次做:暴力求解思路:
暴力求解感受一波。搜索逆序对,时间复杂度:O(n^2),复杂度过大没有通过
public class Solution {
/*1.暴力解法:逆序对判断 O(n^2)--有不必要的比较可以优化
*/
public int InversePairs(int[] array){
int count = 0;
if(array==null) return 0;
for(int i = 0; i<array.length; i++){
for(int j = i; j<array.length; j++){
if(array[i]>array[j])
count++;
}
}
return count%1000000007;
}
}


京公网安备 11010502036488号