题解 | #数组中的逆序对#

数组中的逆序对

http://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5

    //统计逆序对的个数
    int ret = 0;

    public int InversePairs(int[] array) {
        if (array == null || array.length == 0) {
            return 0;
        }
        //使用归并排序的方式统计
        divide(array, 0, array.length - 1);
        return ret;
    }

    private void divide(int[] array, int start, int end) {
        //递归的终止条件
        if (start >= end) {
            return;
        }
        //计算中间值,注意溢出
        int mid = start + (end - start) / 2;
        //递归分
        divide(array, start, mid);
        divide(array, mid + 1, end);
        //治
        merge(array, start, mid, end);
    }

    private void merge(int[] arr, int start, int mid, int end) {
        int[] tmp = new int[end - start + 1];
        //存一下变量
        int i = start;
        int j = mid + 1;
        int k = 0;
        //下面就开始两两进行比较,若前面的数大于后面的数,就构成逆序对
        while (i <= mid && j <= end) {
            //若前面小于后面,直接存进去,并且移动前面数所在的数组的指针即可
            if (arr[i] <= arr[j]) {
                tmp[k++] = arr[i++];
            } else {
                //a[i]>a[j]了,那么这一次,从a[i]开始到a[mid]必定都是大于这个a[j]的,因为此时分治的两边已经是各自有序了
                tmp[k++] = arr[j++];
                ret = (ret + mid - i + 1) % 1000000007;
            }
        }
        //各自还有剩余的没比完,直接赋值即可
        //由于上面的循环条件可知,i和j中必定只有一个可能还有剩余没循环完,所以下面两个循环也只会执行一个。
        while (i <= mid) {
            tmp[k++] = arr[i++];
        }
        while (j <= end) {
            tmp[k++] = arr[j++];
        }
        //覆盖原数组
        for (k = 0; k < tmp.length; k++) {
            arr[start + k] = tmp[k];
        }
    }
}
全部评论

相关推荐

牛客771574427号:恭喜你,华杰
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务