Problem Description

Explanation

To solve this problem efficiently, we can use a modified merge sort algorithm. The idea is to count the number of reverse pairs while merging the two sorted halves of the array. When we compare elements from the left half with elements from the right half, if we find a pair (i, j) such that nums[i] > 2 * nums[j], then we increment the count of reverse pairs by the number of elements remaining in the left half. This is because if nums[i] is greater than 2 * nums[j], then it's also greater than 2 * nums[j+1], 2 * nums[j+2], and so on.

Algorithm:

  1. Define a recursive function mergeSortAndCount that takes the array nums, start index start, and end index end.
  2. If start >= end, return 0.
  3. Calculate the mid index as (start + end) / 2 and recursively call mergeSortAndCount on the left and right halves.
  4. Merge the two sorted halves and count the reverse pairs while merging.
  5. Return the total count of reverse pairs.

Time Complexity:

  • The time complexity of this approach is O(n log n), where n is the number of elements in the array.

Space Complexity:

  • The space complexity is O(n) due to the extra space used for merging.

Solutions

class Solution {
    public int reversePairs(int[] nums) {
        return mergeSortAndCount(nums, 0, nums.length - 1);
    }
    
    private int mergeSortAndCount(int[] nums, int start, int end) {
        if (start >= end) return 0;
        
        int mid = start + (end - start) / 2;
        int count = mergeSortAndCount(nums, start, mid) + mergeSortAndCount(nums, mid + 1, end);
        
        int j = mid + 1;
        for (int i = start; i <= mid; i++) {
            while (j <= end && nums[i] > 2L * nums[j]) j++;
            count += j - (mid + 1);
        }
        
        Arrays.sort(nums, start, end + 1);
        return count;
    }
}

Loading editor...