[LeetCode 493] Reverse Pair (Hard) **

Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j].

You need to return the number of important reverse pairs in the given array.

Example1:

Input: [1,3,2,3,1]
Output: 2

Example2:

Input: [2,4,3,5,1]
Output: 3

Note:

  • The length of the given array will not exceed 50,000.
  • All the numbers in the input array are in the range of 32-bit integer.

Solution: Conquer dive + Merge Sort

  1. 分治的方法:
    • eg:1,3,3,1, 将序列分成左右两段,分别求其reverse pair的数,left == 0, right == 1;
    • 在求左右数的时候,已经分别对其用merge sort排序变为 ==> 1,3, 1,3
    • 再对当前list求其reverse pair的数: 只需要从左到右扫描一遍即可。
      left = start, right = middle
for (int left = start; left < middle; left ++) {
     while (right < end && (long)nums [left] > (long) 2 * nums [right]) {
          right ++;
     }
    count += right - middle;
}
  1. 每次对一个sublist求完reverse pair的数, 都要用merge sort对当前sublist进行排序。这样就可以让上一层求reverse pair的数时,只需要从左到右扫描一遍,就可以得到reverse pair的数。
class Solution {
    public int reversePairs(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        
        int[] copiedNums = new int[nums.length];

        return reversePairsHelper (nums, copiedNums, 0, nums.length);
    }
    
    private int reversePairsHelper (int[] nums, int[] copiedNums, int start, int end) {
        if (start + 1 == end) {
            return 0;
        }
        
        int middle = start + (end - start) / 2;
        int count = reversePairsHelper (nums, copiedNums, start, middle) + reversePairsHelper (nums, copiedNums, middle, end);
        
        int right = middle;
        for (int left = start; left < middle; left ++) {
            while (right < end && (long)nums [left] > (long) 2 * nums [right]) {
                right ++;
            }
            count += right - middle;
        }
        
        mergeSort (nums, copiedNums, start, end);
        return count;
    }
    
    private void mergeSort (int[] nums, int[] copiedNums, int start, int end) {
        if (start + 1 == end) {
            return;
        }
        
        int middle = start + (end - start) / 2;
        int i = start;
        int j = middle;
        int copyStart = start;
        
        while (i < middle && j < end) {
            if (nums[i] < nums[j]) {
                copiedNums [copyStart ++] = nums[i++];
            } else {
                copiedNums [copyStart ++] = nums[j++];
            }
        }
        
        while (i < middle) {
            copiedNums [copyStart ++] = nums[i++];
        }
        while (j < end) {
            copiedNums [copyStart ++] = nums[j++];
        }
        
        //System.out.println (Arrays.toString(copiedNums));
        
        for (i = start; i < end; i++) {
            nums [i] = copiedNums[i];
        }
        
        //System.out.println (Arrays.toString(nums));
        
    }
}

你可能感兴趣的:([LeetCode 493] Reverse Pair (Hard) **)