Reverse Pairs

Count pairs where i precedes j and nums[i] exceeds twice nums[j] using a merge-sort with cross-count.

Hard
Time O(n log n) Space O(n)
LeetCode
6 min read
merge-sort divide-and-conquer

Problem#

Return the number of “reverse pairs” — pairs (i, j) where i < j and nums[i] > 2 * nums[j].

Examples#

  • nums = [1,3,2,3,1]2
  • nums = [2,4,3,5,1]3

Constraints#

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

Approach#

Standard merge sort with an extra cross-count step. After both halves are sorted but before the merge, for each i in the left half advance j in the right half while nums[i] > 2L * nums[j] and add the j-distance.

Solution#

Reverse Pairs
class Solution {
public:
int reversePairs(vector<int>& nums) {
vector<int> buf(nums.size());
return mergeSort(nums, buf, 0, (int)nums.size() - 1);
}
private:
int mergeSort(vector<int>& a, vector<int>& buf, int lo, int hi) {
if (lo >= hi) return 0;
int mid = lo + (hi - lo) / 2;
int count = mergeSort(a, buf, lo, mid) + mergeSort(a, buf, mid + 1, hi);
int j = mid + 1;
for (int i = lo; i <= mid; ++i) {
while (j <= hi && (long long)a[i] > 2LL * a[j]) ++j;
count += j - (mid + 1);
}
// merge
int p = lo, q = mid + 1, k = lo;
while (p <= mid && q <= hi) buf[k++] = (a[p] <= a[q] ? a[p++] : a[q++]);
while (p <= mid) buf[k++] = a[p++];
while (q <= hi) buf[k++] = a[q++];
for (int t = lo; t <= hi; ++t) a[t] = buf[t];
return count;
}
};

Editorial#

The crucial observation: within a merge-sort recursion, all cross-pairs (i in left, j in right) already satisfy i < j. Since both halves are sorted, the j pointer only moves forward as i increases. Use long long to avoid overflow on 2 * nums[j].

Complexity#

  • Time: O(n log n).
  • Space: O(n).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.