在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
/**
* [归并排序]在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。
* 并将P对1000000007取模的结果输出。 即输出P%1000000007
*
* @author pomay
*
*/
public class Solution_InversePairs
{
public int InversePairs(int[] array)
{
if (array == null || array.length < 0)
return 0;
int[] assist = new int[array.length];// 辅助数组
for (int i = 0; i < array.length; i++)
assist[i] = array[i];
int count = InversePairsCore(array, assist, 0, array.length - 1);
return count;
}
// 一边合并相邻的子数组,一边统计逆序对的数目
private int InversePairsCore(int[] array, int[] assist, int start, int end)
{
if (start == end)
{
assist[start] = array[start];
return 0;
}
int length = (end - start) / 2;// 分成两部分,每部分长度
// 在递归的时候将assist作为array传入,解决排序
int left = InversePairsCore(assist, array, start, start + length) % 1000000007;
int right = InversePairsCore(assist, array, start + length + 1, end) % 1000000007;
int i = start + length;// i为前半段最后一个数字下标
int j = end;// j为后半段最后一个数字下标
int indexCopy = end;// 辅助数组从后往前,确保辅助数组是递增的
int count = 0;
while (i >= start && j >= start + length + 1)
{
if (array[i] > array[j])
{
assist[indexCopy--] = array[i--];
count += j - (start + length);
if (count >= 1000000007)// 数值过大求余
count %= 1000000007;
} else
assist[indexCopy--] = array[j--];
}
for (; i >= start; --i)// 前半段若还有剩下
assist[indexCopy--] = array[i];
for (; j >= start + length + 1; --j)// 后半段若还有剩下
assist[indexCopy--] = array[j];
return (left + right + count) % 1000000007;
}
public static void main(String[] args)
{
int[] array =
{ 1, 2, 3, 4, 5, 6, 7, 0 };
Solution_InversePairs s = new Solution_InversePairs();
System.out.println(s.InversePairs(array));
}
}