Merge sort + two pointers
Time O(n log n) Space O(n)For each i in the left half, advance j in the right half while nums[i] > 2 × nums[j]; add (j − mid − 1). Then merge normally.
nums = [1, 3, 2, 3, 1]Step 1/4Split into [1, 3, 2] and [3, 1].
class Solution {
public int reversePairs(int[] nums) {
return sort(nums, new int[nums.length], 0, nums.length - 1);
}
private int sort(int[] a, int[] tmp, int lo, int hi) {
if (lo >= hi) return 0;
int mid = (lo + hi) >>> 1;
int count = sort(a, tmp, lo, mid) + sort(a, tmp, mid + 1, hi);
for (int i = lo, j = mid + 1; i <= mid; i++) {
while (j <= hi && (long) a[i] > 2L * a[j]) j++;
count += j - mid - 1;
}
int i = lo, j = mid + 1, k = lo;
while (i <= mid || j <= hi) tmp[k++] = (j > hi || (i <= mid && a[i] <= a[j])) ? a[i++] : a[j++];
System.arraycopy(tmp, lo, a, lo, hi - lo + 1);
return count;
}
}Verdict: Counting and merging are separate passes.