牛客网刷题之数组中的逆序对

来源:互联网 发布:超市盘点软件 编辑:程序博客网 时间:2024/06/08 10:43

题目描述:

这里写图片描述

解题思路:

  求逆序对过程类似归并排序。归并排序的基本思想就是:将数组划分为左右两部分,归并排序左部分,归并排序右部分,然后 Merge 左右两个数组为一个新的数组,从而完成排序。
  该思想应用到题目中,假设我们将数组划分为两部分,左边数组有leftNum个逆序对,右边有rightNum个逆序对,那么剩余的逆序对必然是一个数出现在左边部分,一个数出现在右边部分,并且满足出现左边部分的数 a[i] > a[j]。由于左右部分依然排序,所以每当出现array[left]>array[right],必然会增加right-mid个逆序对。

题解:

public int InversePairs(int[] array) {        if (array == null || array.length <= 0) {            return 0;        }        return mergeSort(array, 0, array.length - 1);    }    public int mergeSort(int[] array, int start, int end) {        /*         * 递归结束条件         * */        if (start == end) {            return 0;        }        int mid = (start + end) >> 1;        int leftNum = mergeSort(array, start, mid);        int rightNum = mergeSort(array, mid + 1, end);        int left = mid;        int right = end;        int index = end - start;        int temp[] = new int[end - start + 1];        int count = 0;        while (left >= start && right >= mid + 1) {            if (array[left] > array[right]) {                temp[index--] = array[left--];                count += (right - mid);                if (count > 1000000007)// 数值过大求余                {                    count %= 1000000007;                }            } else {                temp[index--] = array[right--];            }        }        /*         * 右边数组已为空         * */        while (left >= start) {            temp[index--] = array[left--];        }        /*         * 左边数组已为空         * */        while (right >= mid + 1) {            temp[index--] = array[right--];        }        // 将临时数组赋值给原数组        int i = 0;        while (start <= end) {            array[start++] = temp[i++];        }        return (count + leftNum + rightNum) % 1000000007;    }

ac结果:

这里写图片描述

0 0
原创粉丝点击