## Algorithm

Problem Name: 493. Reverse Pairs

Given an integer array `nums`, return the number of reverse pairs in the array.

A reverse pair is a pair `(i, j)` where:

• `0 <= i < j < nums.length` and
• `nums[i] > 2 * nums[j]`.

Example 1:

```Input: nums = [1,3,2,3,1]
Output: 2
Explanation: The reverse pairs are:
(1, 4) --> nums[1] = 3, nums[4] = 1, 3 > 2 * 1
(3, 4) --> nums[3] = 3, nums[4] = 1, 3 > 2 * 1
```

Example 2:

```Input: nums = [2,4,3,5,1]
Output: 3
Explanation: The reverse pairs are:
(1, 4) --> nums[1] = 4, nums[4] = 1, 4 > 2 * 1
(2, 4) --> nums[2] = 3, nums[4] = 1, 3 > 2 * 1
(3, 4) --> nums[3] = 5, nums[4] = 1, 5 > 2 * 1
```

Constraints:

• `1 <= nums.length <= 5 * 104`
• `-231 <= nums[i] <= 231 - 1`

## Code Examples

### #1 Code Example with Javascript Programming

```Code - Javascript Programming```

``````
const reversePairs = function(nums) {
return mergeSort(nums, [], 0, nums.length-1);
};

function mergeSort(arr, temp, left, right){
let mid = Math.floor((left+right)/2), count = 0;
if(left<right){
count+= mergeSort(arr, temp, left, mid);
count+= mergeSort(arr, temp, mid+1, right);
count+= merge(arr, temp, left, mid+1, right);
}
return count;
}

function merge(a, temp, left, mid, right){
let i = left, j = mid, k = left, count=0;
for(let y=left; y < mid; y++>{
while(j<=right && (a[y]>2*a[j])){
j++;
}
count+= (j-(mid));
}
i=left;
j=mid;
while(i < =(mid-1) && j<=right){
if (a[i]>(a[j])) {
temp[k++] = a[j++];
} else {
temp[k++] = a[i++];
}
}
while(i < =(mid-1)){
temp[k++] = a[i++];
}
while(j<=right){
temp[k++] = a[j++];
}
for(let x=left; x < =right; x++){
a[x] = temp[x];
}
return count;
}

// another

/**
* @param {number[]} nums
* @return {number}
*/
const reversePairs = function(nums) {
return mergeSort(nums, 0, nums.length - 1);
};

function mergeSort(nums, s, e) {
if (s >= e) return 0;
let mid = s + Math.floor((e - s) / 2);
let cnt = mergeSort(nums, s, mid) + mergeSort(nums, mid + 1, e);
for (let i = s, j = mid + 1; i  < = mid; i++) {
while (j <= e && nums[i] / 2.0 > nums[j]) j++;
cnt += j - (mid + 1);
}
sortSubArr(nums, s, e + 1);
return cnt;
}

function sortSubArr(arr, s, e) {
const tmp = arr.slice(s, e);
tmp.sort((a, b) => a - b);
arr.splice(s, e - s, ...tmp);
}

// another

/**
* @param {number[]} nums
* @return {number}
*/
function merge(A, start, mid, end) {
let n1 = mid - start + 1
let n2 = end - mid
const L = new Array(n1).fill(0)
const R = new Array(n2).fill(0)

for (let i = 0; i  <  n1; i++) L[i] = A[start + i]
for (let j = 0; j  <  n2; j++) R[j] = A[mid + 1 + j]
let i = 0,
j = 0
for (let k = start; k  < = end; k++) {
if (j >= n2 || (i < n1 && L[i] <= R[j])) A[k] = L[i++]
else A[k] = R[j++]
}
}

function mergesort_and_count(A, start, end) {
if (start < end) {
let mid = start + ((end - start) >> 1)
let count =
mergesort_and_count(A, start, mid) + mergesort_and_count(A, mid + 1, end)
let j = mid + 1
for (let i = start; i  < = mid; i++) {
while (j <= end && A[i] > A[j] * 2) j++
count += j - (mid + 1)
}
merge(A, start, mid, end)
return count
} else return 0
}

function reversePairs(nums) {
return mergesort_and_count(nums, 0, nums.length - 1)
}
``````
Copy The Code &

Input

cmd
nums = [1,3,2,3,1]

Output

cmd
2

### #2 Code Example with Python Programming

```Code - Python Programming```

``````
class Solution:
def reversePairs(self, nums: List[int]) -> int:
res = [0]
def merge(nums):
if len(nums) <= 1: return nums
left, right = merge(nums[:len(nums)//2]), merge(nums[len(nums)//2:])
for r in right:
add = len(left) - bisect.bisect(left, 2 * r)
return sorted(left+right)
merge(nums)
return res[0]
``````
Copy The Code &

Input

cmd
nums = [1,3,2,3,1]

Output

cmd
2

### #3 Code Example with C# Programming

```Code - C# Programming```

``````
namespace LeetCode
{
public class _0493_ReversePairs
{
public int ReversePairs(int[] nums)
{
return MergeSortAndCount(nums, 0, nums.Length - 1);
}

private int MergeSortAndCount(int[] nums, int start, int end)
{
if (start  <  end)
{
int mid = (start + end) / 2;
int count = MergeSortAndCount(nums, start, mid) + MergeSortAndCount(nums, mid + 1, end);
int j = mid + 1;
for (int i = start; i  < = mid; i++)
{
while (j <= end && nums[i] > nums[j] * 2L)
j++;
count += j - (mid + 1);
}
Merge(nums, start, mid, end);
return count;
}
else
return 0;
}

private void Merge(int[] nums, int start, int mid, int end)
{
int n1 = mid - start + 1;
int n2 = end - mid;
var L = new int[n1];
var R = new int[n2];

int i = 0, j = 0;
for (i = 0; i  <  n1; i++)
L[i] = nums[start + i];
for (j = 0; j  <  n2; j++)
R[j] = nums[mid + 1 + j];
i = 0; j = 0;
for (int k = start; k  < = end; k++)
{
if (j >= n2 || (i < n1 && L[i] <= R[j]))
nums[k] = L[i++];
else
nums[k] = R[j++];
}
}
}
}
``````
Copy The Code &

Input

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

Output

cmd
3