Explorer
Data Structures & Algorithms

Find number of pairs where i < j and nums[i] > 2 * nums[j] using modified merge sort.

Problem Statement

Given an integer array `nums`, return the number of reverse pairs in the array. A reverse pair is a pair `(i, j)` where `0 <= i < j < nums.length` and `nums[i] > 2 * nums[j]`.

Examples

Input: nums = [1, 3, 2, 3, 1]

Output: 2

Explanation: The reverse pairs are: (1, 4) -> 3 > 2 * 1, and (3, 4) -> 3 > 2 * 1.

Input: nums = [2, 4, 3, 5, 1]

Output: 3

Explanation: Combining the input according to Reverse Pairs logic yields 3.

Complexity

Time Complexity: O(N log N)

Space Complexity: O(N)

Hints

šŸ’” Hint 1: A reverse pair is (i, j) such that i < j and nums[i] > 2 * nums[j]. šŸ’” Hint 2: Like inversion counting, this can be solved during Merge Sort in O(N log N). šŸ’” Hint 3: Before merging two sorted halves, use two pointers to count all pairs where nums[i] > 2 * nums[j].

Editorial & Approach

Problem Overview & Intuition

A reverse pair requires nums[i] > 2 * nums[j] with i < j. Using Divide and Conquer (Merge Sort), because both left and right subarrays are sorted, for each left element we can advance a pointer in the right subarray monotonically in O(N) time per level.

Step-by-Step Approach

  1. Divide nums recursively using merge sort.
  2. Count reverse pairs between the sorted halves before merging: loop i in left, advance rightPtr while nums[i] > 2 * nums[rightPtr].
  3. Merge the two sorted halves.
  4. Return total reverse pairs.

Optimal Implementation (JavaScript)

function reversePairs(nums) {
  function mergeSort(left, right) {
    if (left >= right) return 0;
    const mid = Math.floor((left + right) / 2);
    let count = mergeSort(left, mid) + mergeSort(mid + 1, right);
    count += countPairs(left, mid, right);
    merge(left, mid, right);
    return count;
  }
  function countPairs(left, mid, right) {
    let count = 0, rightPtr = mid + 1;
    for (let i = left; i <= mid; i++) {
      while (rightPtr <= right && nums[i] > 2 * nums[rightPtr]) rightPtr++;
      count += (rightPtr - (mid + 1));
    }
    return count;
  }
  function merge(left, mid, right) {
    const temp = [];
    let i = left, j = mid + 1;
    while (i <= mid && j <= right) {
      if (nums[i] <= nums[j]) temp.push(nums[i++]);
      else temp.push(nums[j++]);
    }
    while (i <= mid) temp.push(nums[i++]);
    while (j <= right) temp.push(nums[j++]);
    for (let p = 0; p < temp.length; p++) nums[left + p] = temp[p];
  }
  return mergeSort(0, nums.length - 1);
}

Complexity Analysis

Time Complexity O(N log N) — O(N) work per recursion level.
Space Complexity O(N) — auxiliary storage for merging.

Edge Cases & Corner Traps Handled

  • Single element array: returns 0.
  • Negative numbers: properly compared.
  • Array sorted in ascending order.

Reverse Pairs

Hard
Given an integer array `nums`, return the number of reverse pairs in the array. A reverse pair is a pair `(i, j)` where `0 <= i < j < nums.length` and `nums[i] > 2 * nums[j]`.
Example Scenarios
1Example 1
Input: nums = [1, 3, 2, 3, 1]
Output: 2
Explanation:

The reverse pairs are: (1, 4) -> 3 > 2 * 1, and (3, 4) -> 3 > 2 * 1.

2Example 2
Input: nums = [2, 4, 3, 5, 1]
Output: 3
Explanation:

Combining the input according to Reverse Pairs logic yields 3.

Editor
Loading Editor...
nums =
[1, 3, 2, 3, 1]
Output:Click "Run" above to execute and verify your code here.
2