From 2b71f994be21e9dae028a32eb60451fb85f786ee Mon Sep 17 00:00:00 2001 From: Ajay-Dhangar Date: Fri, 19 Jul 2024 09:04:27 +0530 Subject: [PATCH] update file --- .../0400-0499/0493-reverse-pairs.md | 496 ++++++++++++------ 1 file changed, 324 insertions(+), 172 deletions(-) diff --git a/dsa-solutions/lc-solutions/0400-0499/0493-reverse-pairs.md b/dsa-solutions/lc-solutions/0400-0499/0493-reverse-pairs.md index ab99d358c..861effb08 100644 --- a/dsa-solutions/lc-solutions/0400-0499/0493-reverse-pairs.md +++ b/dsa-solutions/lc-solutions/0400-0499/0493-reverse-pairs.md @@ -1,172 +1,324 @@ ---- -id: reverse-pairs -title: Reverse Pairs -sidebar_label: 0493 - Reverse Pairs -tags: - - Leetcode - - Merge Sort ---- - -## Problem Statement - -Given an integer array `nums`, return the number of reverse pairs in the array. - -A reverse pair is defined as a pair `(i, j)` where: - -- $0 <= i < j < nums.length and$ -- $nums[i] > 2 * nums[j].$ - -## Examples - -### 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$ - -## Algorithm - -To solve this problem efficiently, we can use a modified merge sort algorithm, which not only sorts the array but also counts the number of reverse pairs during the merging process. The idea is to leverage the divide-and-conquer approach to count pairs in `O(n log n)` time complexity. - -### Steps: - -1. **Divide**: Split the array into two halves. -2. **Count**: Count the reverse pairs in each half recursively. -3. **Merge and Count**: While merging the two halves, count the reverse pairs where one element is from the left half and the other is from the right half. - -## Code - -### Python - -```python -class Solution: - def reversePairs(self, nums: List[int]) -> int: - def merge_sort(nums, l, r): - if l >= r: - return 0 - - mid = (l + r) // 2 - count = merge_sort(nums, l, mid) + merge_sort(nums, mid + 1, r) - - j = mid + 1 - for i in range(l, mid + 1): - while j <= r and nums[i] > 2 * nums[j]: - j += 1 - count += j - (mid + 1) - - nums[l:r + 1] = sorted(nums[l:r + 1]) - return count - - return merge_sort(nums, 0, len(nums) - 1) -``` - -### C++ - -```cpp -#include -using namespace std; - -class Solution { -public: - int reversePairs(vector& nums) { - return reversePairsSub(nums, 0, nums.size() - 1); - } - -private: - int reversePairsSub(vector& nums, int l, int r) { - if (l >= r) return 0; - - int m = l + ((r - l) >> 1); - int res = reversePairsSub(nums, l, m) + reversePairsSub(nums, m + 1, r); - - int i = l, j = m + 1, k = 0, p = m + 1; - vector merge(r - l + 1); - - while (i <= m) { - while (p <= r && nums[i] > 2L * nums[p]) p++; - res += p - (m + 1); - - while (j <= r && nums[i] >= nums[j]) merge[k++] = nums[j++]; - merge[k++] = nums[i++]; - } - - while (j <= r) merge[k++] = nums[j++]; - - copy(merge.begin(), merge.end(), nums.begin() + l); - - return res; - } -}; -``` - -### Java - -```java -import java.util.Arrays; - -class Solution { - public int reversePairs(int[] nums) { - return mergeSort(nums, 0, nums.length - 1); - } - - private int mergeSort(int[] nums, int left, int right) { - if (left >= right) return 0; - - int mid = left + (right - left) / 2; - int count = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right); - - int j = mid + 1; - for (int i = left; i <= mid; i++) { - while (j <= right && nums[i] > 2L * nums[j]) j++; - count += j - (mid + 1); - } - - Arrays.sort(nums, left, right + 1); - return count; - } -} -``` - -### JavaScript - -```javascript -var reversePairs = function (nums) { - function mergeSort(nums, left, right) { - if (left >= right) return 0; - - let mid = left + Math.floor((right - left) / 2); - let count = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right); - - let j = mid + 1; - for (let i = left; i <= mid; i++) { - while (j <= right && nums[i] > 2 * nums[j]) j++; - count += j - (mid + 1); - } - - nums.splice( - left, - right - left + 1, - ...nums.slice(left, right + 1).sort((a, b) => a - b) - ); - return count; - } - - return mergeSort(nums, 0, nums.length - 1); -}; -``` +--- +id: reverse-pairs +title: Reverse Pairs +sidebar_label: 493-Reverse-Pairs +tags: + - Array + - Binary Search + - Divide and conquer + - Binary Indexed Tree + - Segment Tree + - Merge Sort + - Ordered Set +description: The problem is to reverse the pairs. +sidebar_position: 2667 +--- + +## Problem Statement + +### Problem Description + +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]`. + +### Examples + +**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 * 10^4` + +## Solution of Given Problem + +### Intuition and Approach + +The intuition behind this solution is to use a modified Merge Sort algorithm to count the number of reverse pairs in the array. + + +### Approaches + +- Divide the array into smaller subarrays until each subarray has only one element. +- Merge the subarrays back together, counting the number of reverse pairs between each pair of subarrays. +- The merge step is done in a way that ensures the count of reverse pairs is accurate. + + +#### Codes in Different Languages + + + + + ```javascript + function mergeSortedArrays(nums, left, mid, right, temp) { + let i = left, j = mid + 1, k = 0; + while (i <= mid && j <= right) { + if (nums[i] <= nums[j]) temp[k++] = nums[i++]; + else temp[k++] = nums[j++]; + } + while (i <= mid) temp[k++] = nums[i++]; + while (j <= right) temp[k++] = nums[j++]; +} + +function merge(nums, left, mid, right) { + let count = 0; + let j = mid + 1; + for (let i = left; i <= mid; i++) { + while (j <= right && nums[i] > 2 * nums[j]) j++; + count += j - mid - 1; + } + let temp = new Array(right - left + 1); + mergeSortedArrays(nums, left, mid, right, temp); + for (let i = left; i <= right; i++) nums[i] = temp[i - left]; + return count; +} +function mergeSort(nums, left, right) { + if (left >= right) return 0; + let mid = left + (right - left) / 2; + let count = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right); + count += merge(nums, left, mid, right); + return count; +} + +class Solution { + reversePairs(nums) { + return mergeSort(nums, 0, nums.length - 1); + } +} + + + ``` + + + + + ```typescript + function mergeSortedArrays(nums: number[], left: number, mid: number, right: number, temp: number[]) { + let i = left, j = mid + 1, k = 0; + while (i <= mid && j <= right) { + if (nums[i] <= nums[j]) temp[k++] = nums[i++]; + else temp[k++] = nums[j++]; + } + while (i <= mid) temp[k++] = nums[i++]; + while (j <= right) temp[k++] = nums[j++]; +} + +function merge(nums: number[], left: number, mid: number, right: number) { + let count = 0; + let j = mid + 1; + for (let i = left; i <= mid; i++) { + while (j <= right && nums[i] > 2 * nums[j]) j++; + count += j - mid - 1; + } + let temp = new Array(right - left + 1); + mergeSortedArrays(nums, left, mid, right, temp); + for (let i = left; i <= right; i++) nums[i] = temp[i - left]; + return count; +} +function mergeSort(nums: number[], left: number, right: number) { + if (left >= right) return 0; + let mid = left + (right - left) / 2; + let count = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right); + count += merge(nums, left, mid, right); + return count; +} + +class Solution { + reversePairs(nums: number[]) { + return mergeSort(nums, 0, nums.length - 1); + } +} + + ``` + + + + + ```python + def merge_sorted_arrays(nums, left, mid, right, temp): + i, j, k = left, mid + 1, 0 + while i <= mid and j <= right: + if nums[i] <= nums[j]: + temp[k] = nums[i] + i += 1 + else: + temp[k] = nums[j] + j += 1 + k += 1 + while i <= mid: + temp[k] = nums[i] + i += 1 + k += 1 + while j <= right: + temp[k] = nums[j] + j += 1 + k += 1 + +def merge(nums, left, mid, right): + count = 0 + j = mid + 1 + for i in range(left, mid + 1): + while j <= right and nums[i] > 2 * nums[j]: + j += 1 + count += j - mid - 1 + temp = [0] * (right - left + 1) + merge_sorted_arrays(nums, left, mid, right, temp) + for i in range(left, right + 1): + nums[i] = temp[i - left] + return count + +def merge_sort(nums, left, right): + if left >= right: + return 0 + mid = left + (right - left) // 2 + count = merge_sort(nums, left, mid) + merge_sort(nums, mid + 1, right) + count += merge(nums, left, mid, right) + return count + +class Solution: + def reversePairs(self, nums): + return merge_sort(nums, 0, len(nums) - 1) + + ``` + + + + + ```java + public class Solution { + public int reversePairs(int[] nums) { + return mergeSort(nums, 0, nums.length - 1); + } + + public int mergeSort(int[] nums, int left, int right) { + if (left >= right) { + return 0; + } + int mid = left + (right - left) / 2; + int count = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right); + count += merge(nums, left, mid, right); + return count; + } + public int merge(int[] nums, int left, int mid, int right) { + int count = 0; + int j = mid + 1; + for (int i = left; i <= mid; i++) { + while (j <= right && nums[i] > 2 * nums[j]) { + j++; + } + count += j - mid - 1; + } + int[] temp = new int[right - left + 1]; + mergeSortedArrays(nums, left, mid, right, temp); + for (int i = left; i <= right; i++) { + nums[i] = temp[i - left]; + } + return count; + } + + public void + mergeSortedArrays(int[] nums, int left, int mid, int right, int[] temp) { + int i = left, j = mid + 1, k = 0; + while (i <= mid && j <= right) { + if (nums[i] <= nums[j]) { + temp[k++] = nums[i++]; + } else { + temp[k++] = nums[j++]; + } + } + while (i <= mid) { + temp[k++] = nums[i++]; + } + while (j <= right) { + temp[k++] = nums[j++]; + } + } +} + + ``` + + + + ```cpp + void mergeSortedArrays(vector& nums, int left, int mid, int right, vector& temp) { + int i = left, j = mid + 1, k = 0; + while (i <= mid && j <= right) { + if (nums[i] <= nums[j]) temp[k++] = nums[i++]; + else temp[k++] = nums[j++]; + } + while (i <= mid) temp[k++] = nums[i++]; + while (j <= right) temp[k++] = nums[j++]; +} +int merge(vector& nums, int left, int mid, int right) { + int count = 0; + int j = mid + 1; + for (int i = left; i <= mid; i++) { + while (j <= right && nums[i] > 2 * nums[j]) j++; + count += j - mid - 1; + } + vector temp(right - left + 1); + mergeSortedArrays(nums, left, mid, right, temp); + for (int i = left; i <= right; i++) nums[i] = temp[i - left]; + return count; +} +int mergeSort(vector& nums, int left, int right) { + if (left >= right) return 0; + int mid = left + (right - left) / 2; + int count = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right); + count += merge(nums, left, mid, right); + return count; +} + + +class Solution { +public: + int reversePairs(vector& nums) { + return mergeSort(nums, 0, nums.size() - 1); + + + } +}; + ``` + + + +### Complexity Analysis + +- **Time Complexity**: $$O(n*log(n))$$, where n is the length of the input array. This is because the solution uses a modified Merge Sort algorithm, which has a time complexity of O(n log n). + + +- **Space Complexity**: $$O(n)$$, where n is the length of the input array. This is because the solution uses a temporary array to store the merged sorted arrays. + + + +--- + +

Authors:

+ +
+{['Ishitamukherjee2004', 'ImmidiSivani'].map(username => ( + +))} +