493. 翻转对

给定一个数组 nums ,如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对。

你需要返回给定数组中的重要翻转对的数量。

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


当移动一个指针位置时,该位置的情况是否已经全部考虑到?

比如

 while (p1 <= mid && p2 <= r) {
    if (nums[p1] > nums[p2]) {
        if (nums[p1] <= 2L * nums[p2]) {
            ret += (r - p2 + 1);
        }
        helper[index++] = nums[p1++];
    } else {
        helper[index++] = nums[p2++];
    }
}

中移动 p1的方式是不合理的,因为此时(p1, p2)不满足要求,可能是p2太大,即后面的元素可能有更小的p2‘使得(p1, p2')满足要求。

class Solution {

    private int[] helper;

    private int mergeSort(int[] nums, int l, int r) {
        if (l >= r) {
            return 0;
        }
        int ret = 0;
        int mid = (l + r) >> 1;
        ret += mergeSort(nums, l, mid);
        ret += mergeSort(nums, mid + 1, r);
        int p1 = l, p2 = mid + 1, index = l;


        while (p1 <= mid) {
            while (p2 <= r && nums[p1] <= 2L * nums[p2]) {
                p2++;
            }
            ret += (r - p2 + 1);
            p1++;
        }

        p1 = l;
        p2 = mid + 1;

        while (p1 <= mid && p2 <= r) {
            if (nums[p1] > nums[p2]) {
                helper[index++] = nums[p1++];
            } else {
                helper[index++] = nums[p2++];
            }
        }

        while (p1 <= mid) {
            helper[index++] = nums[p1++];
        }

        while (p2 <= r) {
            helper[index++] = nums[p2++];
        }
        System.arraycopy(helper, l, nums, l, r - l + 1);
        return ret;
    }

    public int reversePairs(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        this.helper = new int[nums.length];
        return mergeSort(nums, 0, nums.length - 1);
    }
}
posted @ 2021-12-10 16:32  Tianyiya  阅读(32)  评论(0)    收藏  举报