The problem. Given an integer array nums, return the number of reverse pairs: index pairs i < j with nums[i] > 2 · nums[j].
nums = [1, 3, 2, 3, 1] -> 2 (3 > 2·1 at indexes 1,4 and 3,4)
nums = [2, 4, 3, 5, 1] -> 3 (4, 3 and 5 are each more than 2·1)It's Count Inversions with a different condition. Split in half; pairs inside each half are counted recursively; pairs across the halves are counted while both halves are sorted. But the condition a[i] > 2 · a[j] doesn't match the merge's own comparison, so do a separate counting pass first: for each left value a[i] in increasing order, move j forward through the right half while a[i] > 2 · a[j]. Since a[i] only grows, j never moves back — the whole pass is linear. Then merge as usual.
function reversePairs(nums) { let count = 0; for (let i = 0; i < nums.length; i++) { for (let j = i + 1; j < nums.length; j++) { if (nums[i] > 2 * nums[j]) count++; } } return count;}Time O(n²), space O(1). Too slow for 5 × 10⁴ values.
Before each merge, two pointers count the pairs across the sorted halves in one sweep.
function reversePairs(nums) { const a = [...nums]; const sortCount = (lo, hi) => { // sorts a[lo..hi), returns the reverse pairs inside it if (hi - lo <= 1) return 0; const mid = (lo + hi) >> 1; let count = sortCount(lo, mid) + sortCount(mid, hi); let j = mid; for (let i = lo; i < mid; i++) { // both halves are sorted: j only moves forward while (j < hi && a[i] > 2 * a[j]) j++; count += j - mid; // a[mid..j) are all small enough for a[i] } const merged = []; let p = lo, q = mid; while (p < mid && q < hi) merged.push(a[p] <= a[q] ? a[p++] : a[q++]); while (p < mid) merged.push(a[p++]); while (q < hi) merged.push(a[q++]); for (let k = 0; k < merged.length; k++) a[lo + k] = merged[k]; return count; }; return sortCount(0, a.length);}Time O(n log n), space O(n). Each level does one linear counting pass and one linear merge. In Java and C++, compute 2 * a[j] in 64 bits — with values up to 2³¹ − 1 it overflows an int.
A Fenwick tree (binary indexed tree) over the compressed values solves it in O(n log n) too — useful when the condition can't be counted with two pointers.
[-5, -5]: -5 > 2 · (-5) = -10, so that's 1 pair.[2147483647, 2147483647]: 2 · 2147483647 overflows a 32-bit int.[1, 1]: 1 > 2 is false, 0 pairs.a[p] <= a[q], not the pair condition; keep the passes separate.a[i] > a[j] fits inside the merge itself. Previous lesson.Was this helpful?