数组中的逆序对
题目描述:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P
。并将P
对1000000007
取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
输入:
1,2,3,4,5,6,7,0
输出:
7
思路:
首先想到的是暴力解法,但会超时。如果采用归并排序的思想,递归的分成两段,后面一段的首位只要比前面一段的首位小,逆序数就增加前面一段的总长度,这样一来排序排好了,逆序数对的个数也就出来了,时间复杂度可以降到O(nlogn)
。
代码:
public class Solution {
// 统计逆序数对
int count = 0;
// 递归主体
private void mergeSort(int array[], int start, int end, int tmp[]){
if (start < end){
int mid = (start + end) / 2;
mergeSort(array, start, mid, tmp);
mergeSort(array, mid + 1, end, tmp);
merge(array, start, mid, end, tmp);
}
}
// 二路归并
private void merge(int array[], int start, int mid, int end, int tmp[] ){
int i = start,j = mid + 1,k = 0;
while (i <= mid && j <= end){
if (array[i] < array[j]){
tmp[k++] = array[i++];
}
else {
count = (count + mid - i + 1) % 1000000007;
tmp[k++] = array[j++];
}
}
while (i <= mid){
tmp[k++] = array[i++];
}
while (j <= end){
tmp[k++] = array[j++];
}
k = 0;
while (start <= end){
array[start++] = tmp[k++];
}
}
public int InversePairs(int [] array) {
// 创建辅助数组防止递归过程中不断创建数组消耗资源
int tmp[] = new int[array.length];
mergeSort(array, 0, array.length-1, tmp);
return count;
}
}
网友评论