题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数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
解题思路:
直观解法是两次循环遍历依次查找,时间复杂度O(n^2),显然不合适。这里采用归并排序求解,时间复杂度O(nlogn)
与归并排序的不同之处在于当左半部分指向的元素 > 右半部分指向的元素,说明产生了逆序对,并且由于左右两部分都是排过序的,所以左边指向元素之后的所有元素都大于右边指向的元素,逆序对应该是mid-i+1个,由于复制数组偏移了l个,所以为mid-l-i+1个
public class Solution {
public int InversePairs(int [] array) {
res = 0;
if(array.length < 2)
return 0;
helper(array, 0, array.length-1);
return res;
}
private int res;
private void helper(int[] array, int l, int r){
if(l >= r)
return;
int mid = l + ((r-l)>>1);
helper(array, l, mid);
helper(array, mid+1, r);
merge(array, l, mid, r);
}
private void merge(int[] array, int l, int mid, int r){
int[] temp = new int[r-l+1];
for(int k=l; k<=r; k++)
temp[k-l] = array[k];
int i = 0;
int j = mid-l+1;
for(int k=l; k<=r; k++){
if(i > mid-l)
array[k] = temp[j++];
else if(j > r-l)
array[k] = temp[i++];
else if(temp[i] > temp[j]){
res = (res+mid-l-i+1)%1000000007;
array[k] = temp[j++];
}else
array[k] = temp[i++];
}
}
}

博客围绕数组逆序对问题展开,要求输入数组求出逆序对总数P并对1000000007取模输出。直观解法时间复杂度高,采用归并排序求解,时间复杂度为O(nlogn),当左半部分元素大于右半部分元素时可计算逆序对数量。
239

被折叠的 条评论
为什么被折叠?



