数组中的逆序对
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述
题目保证输入的数组中没有的相同的数字
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
示例
输入
1,2,3,4,5,6,7,0
输出
7
分析
看似很简单的题目,但是要考虑时间复杂度不能太高,因为输入的数组可能非常大。归并排序的改进,把数据分成前后两个数组(递归分到每个数组仅有一个数据项),合并数组,合并时,出现前面的数组值array[i]大于后面数组值array[j]时;则前面
数组array[i]~array[mid]都是大于array[j]的,count += mid+1 - i + 1 。
贴出代码
public class Solution {
int cnt;
public int InversePairs(int [] array) {
cnt = 0;
if (array != null || array.length != 0){
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;
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];
}
}
}

更多精彩