leetcode 剑指 Offer 51. 数组中的逆序对

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

 

示例 1:

输入: [7,5,6,4]
输出: 5
 

限制:

0 <= 数组长度 <= 50000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

采用二路归并排序的思想。

每次合并arr1,arr2的时候,做一步count的统计:

例如 arr1 = [2,4,7]; arr2 = [1,3,4,5]

若 arr1[n] > arr2[m] 表明 arr1.length - n + 1 个数字比 arr2[m]大, 所以 count += (arr1.length - n + 1)。

    private int[] item;
    private int count = 0;
    public int reversePairs(int[] nums) {
        if (nums == null || nums.length < 2) {
            return 0;
        }
        int length = nums.length;
        item = new int[length];
        find(nums, 0, length - 1);
        return count;
    }

    private void find(int[] nums, int st, int end) {
        if (st >= end) {
            return;
        }
        int m = st + ((end - st) >> 1);
        find(nums, st, m);
        find(nums, m + 1, end);
        int i = st;
        int j = m + 1;
        int index = 0;
        while (i <= m && j <= end) {
            if (nums[i] > nums[j]) {
                item[index++] = nums[j++];
                count += (m - i + 1);
            } else {
                item[index++] = nums[i++];
            }
        }
        while (i <= m) {
            item[index++] = nums[i++];
        }
        while (j <= end) {
            item[index++] = nums[j++];
        }
        index = 0;
        for (int k = st; k <= end; k++) {
            nums[k] = item[index++];
        }
    }

posted @ 2021-06-30 17:07  旺仔古李  阅读(28)  评论(0编辑  收藏  举报