Reverse Pairs

hard

You're given an integer array nums. A pair of indices (i, j) is called a reverse pair when:

  • 0 <= i < j < nums.length, and
  • nums[i] > 2 * nums[j] — the earlier value is more than twice the later one.

Return the total number of reverse pairs in nums.

Note that the condition is strict (>), and it compares against double the later value — nums[i] > nums[j] alone is not enough.

Hints

Counting all pairs one by one costs O(n²) — too slow for n = 5 * 10^4. Which classic sorting algorithm naturally splits the array into two halves and visits every cross-half relationship?
Split the array at the middle. Any pair with i in the left half and j in the right half keeps i < j no matter how each half is internally reordered — so you're free to sort the halves before counting cross pairs.
With both halves sorted, walk the left half once while a pointer sweeps the right half forward: once nums[i] > 2 * nums[j], every larger left element also beats nums[j], so the pointer never resets. Count with this sweep, then do a standard merge — count first, merge second.

Common doubts

The merge decides order with nums[i] <= nums[k], but the pair condition here is nums[i] > 2 * nums[j] — two different tests. When the merge pops an element you learn nothing about the doubled condition, so counting mid-merge silently miscounts. Run a dedicated counting sweep first, then merge.
Only when they're negative. x > 2 * x is false for x >= 0 but true for x < 0 — for example [-5, -5] contains one reverse pair, since -5 > -10.
In 32-bit arithmetic, yes — nums[j] can be 2^31 - 1, so doubling it leaves the 32-bit range. In C++ compare as (long long)nums[i] > 2LL * nums[j]. Python, JavaScript, and Go's 64-bit int handle it natively.
No — the definition only needs i < j, and every index in the left half is smaller than every index in the right half regardless of how the halves are shuffled internally. Pairs within a half are counted by the recursive calls before that half was sorted at this level.

Interview follow-ups

Yes. Coordinate-compress the values of nums together with their doubles, sweep j from left to right, and before inserting nums[j] query how many already-seen values exceed 2 * nums[j]. Same O(n log n) time; it's the go-to shape when elements arrive one at a time.
The count-then-merge skeleton is unchanged — only the while condition becomes nums[i] > k * nums[j]. The sweep stays valid because the predicate is still monotone over the sorted halves.
Maintain a Binary Indexed Tree (or balanced BST) over compressed values: for each new element x, add the count of previously seen values greater than 2x, then insert x. That's O(log n) per element.

Fun facts

  • This is Count Inversions with the comparison tightened from bigger to more-than-double — and that tiny change breaks the beloved count-during-merge trick, forcing the cleaner and more general count-then-merge pattern.
  • The forward-only counting sweep reappears almost verbatim in Count of Smaller Numbers After Self and Count of Range Sum — all three are merge sort counting in disguise, differing only in the while condition.
  • The answer itself needs care: with n = 5 * 10^4 the count can reach about 1.25 * 10^9, which still fits a 32-bit int — but only barely; the k-times variant of this problem can push it past.

Asked at

GoogleAmazonMicrosoftUberAdobe
Frequently Sometimes Occasionally
Example 1
Input: nums = [1,3,2,3,1]
Output: 2
Two reverse pairs: (1, 4) since nums[1] = 3 > 2 * nums[4] = 2, and (3, 4) since nums[3] = 3 > 2 * nums[4] = 2.
Example 2
Input: nums = [2,4,3,5,1]
Output: 3
Three reverse pairs, all against nums[4] = 1: (1, 4) with 4 > 2, (2, 4) with 3 > 2, and (3, 4) with 5 > 2.
Example 3
Input: nums = [-5,-5]
Output: 1
-5 > 2 * (-5) = -10, so (0, 1) counts — equal negative values can form a reverse pair.
Constraints

- 1 <= nums.length <= 5 * 10^4 - -2^31 <= nums[i] <= 2^31 - 1

Solve this problem →