LeetCode #493 Hard

Reverse Pairs

Count pairs (i, j) with i < j and nums[i] > 2 * nums[j].

arraymerge-sortdivide-and-conquer
Open on LeetCode ↗
02

Intuition

💡

Checking every pair is O(n²). Merge sort already compares the left half against the right half while sorting — piggyback on it. When both halves are sorted, for each left element the right-half values that violate the condition form a prefix, so a two-pointer sweep counts all cross pairs in linear time per level.

03

Approach

1

Divide

Split the array in half; count pairs entirely inside each half recursively. What's left is pairs that cross the middle.

2

Count cross pairs on sorted halves

With both halves sorted, walk a pointer j over the right half for each left i: advance j while nums[i] > 2*nums[j]. j never moves backward, so the count for the whole level is O(n).

3

Merge as usual

After counting, restore sorted order so the parent call sees a sorted range. The code delegates this to Python's sorted(): because the two halves are already sorted, Timsort detects the runs and merges them in linear time, so the level stays O(n) — an explicit two-pointer merge would be equivalent. Sorting doesn't lose pairs, since counting happened before the order changed across the boundary.

04

Solution & live demo

python
1class Solution:
2 def reversePairs(self, nums):
3 def sort(lo, hi):
4 if hi - lo <= 1: return 0
5 mid = (lo + hi) // 2
6 count = sort(lo, mid) + sort(mid, hi)
7 j = mid
8 for i in range(lo, mid):
9 while j < hi and nums[i] > 2 * nums[j]:
10 j += 1
11 count += j - mid
12 nums[lo:hi] = sorted(nums[lo:hi])
13 return count
14 return sort(0, len(nums))
05

Edge cases

Negative numbers

2*nums[j] handles signs fine; comparisons stay valid on sorted halves.

Overflow in other languages

2× a large int needs 64 bits; Python is safe.

06

Complexity

Time
O(n log n)
Space
O(n)
Merge-sort recursion; counting per level is linear.