Reverse Pairs

Solution For Reverse Pairs

The Reverse Pairs problem on LeetCode requires finding the number of pairs (i, j) where i < j and nums[i] > 2 * nums[j]. The nums array is an integer array of length n. The goal is to come up with an efficient algorithm to solve this problem.

One simple approach to solving this problem is to use brute force. We can compare each pair of elements in the array and count the number of pairs that satisfy the above condition. However, this approach has a time complexity of O(n^2) and is not efficient for large arrays.

A more efficient approach to solving this problem involves using a modified version of merge sort. We can use the divide and conquer strategy to split the array into two halves and recursively solve for each half. Once we have solved for the two halves, we can merge them together while counting the number of pairs that satisfy the given condition.

The key observation in this approach is that the number of reverse pairs can only be found between elements in separate subarrays. This is because if the subarrays are sorted, any reverse pairs must involve an element in the left subarray and an element in the right subarray.

The algorithm for solving this problem using divide and conquer merge sort is as follows:

  1. Define a function to count the number of reverse pairs between two sorted halves of the array. The function takes in two sorted subarrays, the left and right subarrays, as well as their respective lengths.

  2. Initialize a count variable to 0.

  3. Use two indices i and j to traverse the left and right subarrays, respectively.

  4. For each element in the left subarray, find the number of elements in the right subarray that satisfy the given condition (nums[i] > 2 * nums[j]). This can be done using binary search since the right subarray is sorted.

  5. Add the number of reverse pairs found to the count variable and advance the left index.

  6. Merge the two subarrays together to form a single sorted array and return the count variable.

  7. Define a recursive function to split the array into two halves and solve for each half.

  8. Once the two halves are solved, merge them together while counting the number of reverse pairs as described above.

  9. Return the total count of reverse pairs found.

The time complexity of this algorithm is O(n log n) since the merge sort algorithm has a time complexity of O(n log n).

Here is the code to implement the above algorithm in Python:

“`
def reversePairs(nums: List[int]) -> int:
def merge(left: List[int], right: List[int], m: int, n: int) -> int:
i, j = 0, 0
count = 0
while i < m and j < n:
if left[i] > 2 * right[j]:
count += m – i
j += 1
else:
i += 1
return count

def merge_sort(nums: List[int], n: int) -> int:
    if n <= 1:
        return 0
    mid = n // 2
    left = nums[:mid]
    right = nums[mid:]
    count = merge_sort(left, mid) + merge_sort(right, n - mid) + merge(left, right, mid, n - mid)
    nums[:] = sorted(nums)
    return count

return merge_sort(nums, len(nums))

“`
Overall, the above algorithm is very efficient and solves the Reverse Pairs problem on LeetCode with a time complexity of O(n log n).

Step by Step Implementation For Reverse Pairs

class Solution {
    public int reversePairs(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        return mergeSort(nums, 0, nums.length - 1);
    }
    private int mergeSort(int[] nums, int start, int end) {
        if (start >= end) {
            return 0;
        }
        int mid = start + (end - start) / 2;
        int count = mergeSort(nums, start, mid) + mergeSort(nums, mid + 1, end);
        int j = mid + 1;
        for (int i = start; i <= mid; i++) {
            while (j <= end && nums[i] / 2.0 > nums[j]) {
                j++;
            }
            count += j - (mid + 1);
        }
        Arrays.sort(nums, start, end + 1);
        return count;
    }
}
class Solution: 
    def reversePairs(self, nums): 
        return self.mergeSort(nums, 0, len(nums)-1) 
      
    
    def mergeSort(self, nums, l, r): 
        if l < r: 
            m = int((l + (r - 1)) / 2) 
            count = self.mergeSort(nums, l, m) 
            count += self.mergeSort(nums, m + 1, r) 
            count += self.merge(nums, l, m, r) 
            return count 
        return 0
      
    
    def merge(self, nums, l, m, r): 
        count = 0
        i = l 
        j = m + 1
        temp = [] 
        while i <= m and j <= r: 
            if nums[i] <= nums[j]: 
                temp.append(nums[i]) 
                i += 1
            else: 
                temp.append(nums[j]) 
                count += m - i + 1
                j += 1
        while i <= m: 
            temp.append(nums[i]) 
            i += 1
        while j <= r: 
            temp.append(nums[j]) 
            j += 1
        for i in range(l, r + 1): 
            nums[i] = temp[i - l] 
        return count
var reversePairs = function(nums) {
    var count = 0;
    
    for(var i = 0; i < nums.length; i++) {
        for(var j = i+1; j < nums.length; j++) {
            if(nums[i] > nums[j]) {
                count++;
            }
        }
    }
    
    return count;
};
class Solution {
public:
    int reversePairs(vector& nums) {
        int n = nums.size();
        if (n <= 1) return 0;
        vector left(nums.begin(), nums.begin() + n / 2);
        vector right(nums.begin() + n / 2, nums.end());
        int cnt = reversePairs(left) + reversePairs(right);
        for (int i = 0, j = 0; i < left.size(); ++i) {
            while (j < right.size() && left[i] > 2LL * right[j]) ++j;
            cnt += j;
        }
        inplace_merge(left.begin(), left.end(), right.end());
        nums.assign(left.begin(), left.end());
        return cnt;
    }
};
public class Solution {
    public int ReversePairs(int[] nums) {
        // Base case
        if (nums.Length == 0)
        {
            return 0;
        }
        
        // Split the array into left and right halves
        int mid = nums.Length / 2;
        int[] left = new int[mid];
        int[] right = new int[nums.Length - mid];
        Array.Copy(nums, 0, left, 0, mid);
        Array.Copy(nums, mid, right, 0, nums.Length - mid);
        
        // Recurse on the left and right halves
        int leftCount = ReversePairs(left);
        int rightCount = ReversePairs(right);
        
        // Merge the halves and count the reverse pairs
        int[] merged = new int[nums.Length];
        int i = 0;
        int j = 0;
        int k = 0;
        int count = 0;
        while (i < left.Length && j < right.Length)
        {
            if (left[i] <= right[j])
            {
                merged[k] = left[i];
                i++;
            }
            else
            {
                merged[k] = right[j];
                j++;
                count += left.Length - i;
            }
            
            k++;
        }
        
        // Copy over any remaining elements
        while (i < left.Length)
        {
            merged[k] = left[i];
            i++;
            k++;
        }
        
        while (j < right.Length)
        {
            merged[k] = right[j];
            j++;
            k++;
        }
        
        // Copy the merged array back into the original array
        Array.Copy(merged, 0, nums, 0, nums.Length);
        
        // Return the total number of reverse pairs
        return count + leftCount + rightCount;
    }
}


Top 100 Leetcode Practice Problems In Java

Get 30% Off Instantly!
[gravityforms id="5" description="false" titla="false" ajax="true"]