From 7443825bfeb35f4b37a59f4c3e7c5ca859088712 Mon Sep 17 00:00:00 2001 From: Nikita Saini Date: Fri, 7 Jun 2024 23:12:57 +0530 Subject: [PATCH 1/7] Update 004 - Median-of-two-sorted-array Added Solution of lc problem 004 - Median of two sorted array using python --- .../0004-Median-of-two-Sorted-Array.md | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md b/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md index 2f5ffa450..d60f7b072 100644 --- a/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md +++ b/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md @@ -143,6 +143,48 @@ function medianOfTwoSortedArraysProblem() { ### Code in Different Languages +## Python +class Solution: + def findMedianSortedArrays(self, nums1, nums2): + # Ensure nums1 is the smaller array + if len(nums1) > len(nums2): + nums1, nums2 = nums2, nums1 + + m, n = len(nums1), len(nums2) + imin, imax, half_len = 0, m, (m + n + 1) // 2 + + while imin <= imax: + i = (imin + imax) // 2 + j = half_len - i + + if i < m and nums1[i] < nums2[j - 1]: + # i is too small, must increase it + imin = i + 1 + elif i > 0 and nums1[i - 1] > nums2[j]: + # i is too big, must decrease it + imax = i - 1 + else: + # i is perfect + if i == 0: max_of_left = nums2[j - 1] + elif j == 0: max_of_left = nums1[i - 1] + else: max_of_left = max(nums1[i - 1], nums2[j - 1]) + + if (m + n) % 2 == 1: + return max_of_left + + if i == m: min_of_right = nums2[j] + elif j == n: min_of_right = nums1[i] + else: min_of_right = min(nums1[i], nums2[j]) + + return (max_of_left + min_of_right) / 2.0 + +# Example usage: +solution = Solution() +nums1 = [1, 3] +nums2 = [2] +print(solution.findMedianSortedArrays(nums1, nums2)) # Output: 2.0 + + From 0a52e77aafb08fceefaea862658708416a23f7a0 Mon Sep 17 00:00:00 2001 From: Nikita Saini Date: Sat, 8 Jun 2024 10:42:12 +0530 Subject: [PATCH 2/7] Update 004 - Median of two sorted array Update solution of lc 004 - Median of two sorted array --- .../0004-Median-of-two-Sorted-Array.md | 342 +++++++++--------- 1 file changed, 172 insertions(+), 170 deletions(-) diff --git a/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md b/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md index d60f7b072..0bd5af675 100644 --- a/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md +++ b/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md @@ -2,11 +2,11 @@ id: median-of-two-sorted-arrays title: Median of Two Sorted Arrays(Leetcode) sidebar_label: 0004 - Median of Two Sorted Arrays -tags: - - Array - - Binary Search - - Divide and Conquer0 - - LeetCode +tags: + - Array + - Binary Search + - Divide and Conquer0 + - LeetCode description: Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. The overall run time complexity should be $O(log (m+n))$. --- @@ -14,7 +14,7 @@ In this page, we will solve the problem [Median of Two Sorted Arrays](https://le ## Problem Statement -Given two sorted arrays `nums1` and `nums2` of size `m` and `n` respectively, return the median of the two sorted arrays. +Given two sorted arrays `nums1` and `nums2` of size `m` and `n` respectively, return the median of the two sorted arrays. The overall run time complexity should be $O(log (m+n))$. @@ -47,7 +47,7 @@ Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5. ## Solution for Median of Two Sorted Arrays -The **Median of Two Sorted Arrays** is a classic algorithm problem on LeetCode ([Problem 4](https://leetcode.com/problems/median-of-two-sorted-arrays/description/)). It requires finding the median of two sorted arrays. Given two sorted arrays `nums1` and `nums2`, the task is to find the median of the two arrays combined. +The **Median of Two Sorted Arrays** is a classic algorithm problem on LeetCode ([Problem 4](https://leetcode.com/problems/median-of-two-sorted-arrays/description/)). It requires finding the median of two sorted arrays. Given two sorted arrays `nums1` and `nums2`, the task is to find the median of the two arrays combined. Here is an explanation of the intuition and approaches to solve this problem: @@ -69,17 +69,17 @@ The binary search approach involves partitioning the two arrays such that the co 1. Ensure `nums1` is the smaller array. 2. Initialize `low` and `high` for binary search on `nums1`. 3. While `low <= high`: - - Calculate `partitionX` and `partitionY`. - - Set `maxX`, `minX`, `maxY`, `minY`. - - If `maxX <= minY` and `maxY <= minX`: - - If total number of elements is even - - Return average of `max(maxX, maxY)` and `min(minX, minY)`. - - Else - - Return `max(maxX, maxY)`. - - If `maxX > minY`: - - Move `high` to `partitionX - 1`. - - Else: - - Move `low` to `partitionX + 1`. + - Calculate `partitionX` and `partitionY`. + - Set `maxX`, `minX`, `maxY`, `minY`. + - If `maxX <= minY` and `maxY <= minX`: + - If total number of elements is even + - Return average of `max(maxX, maxY)` and `min(minX, minY)`. + - Else + - Return `max(maxX, maxY)`. + - If `maxX > minY`: + - Move `high` to `partitionX - 1`. + - Else: + - Move `low` to `partitionX + 1`. 4. If no median is found, raise an error. ### Implementation and Code @@ -93,21 +93,22 @@ function medianOfTwoSortedArraysProblem() { if (nums1.length > nums2.length) { [nums1, nums2] = [nums2, nums1]; } - + const x = nums1.length; const y = nums2.length; - let low = 0, high = x; - + let low = 0, + high = x; + while (low <= high) { const partitionX = Math.floor((low + high) / 2); const partitionY = Math.floor((x + y + 1) / 2) - partitionX; - - const maxX = (partitionX === 0) ? -Infinity : nums1[partitionX - 1]; - const minX = (partitionX === x) ? Infinity : nums1[partitionX]; - - const maxY = (partitionY === 0) ? -Infinity : nums2[partitionY - 1]; - const minY = (partitionY === y) ? Infinity : nums2[partitionY]; - + + const maxX = partitionX === 0 ? -Infinity : nums1[partitionX - 1]; + const minX = partitionX === x ? Infinity : nums1[partitionX]; + + const maxY = partitionY === 0 ? -Infinity : nums2[partitionY - 1]; + const minY = partitionY === y ? Infinity : nums2[partitionY]; + if (maxX <= minY && maxY <= minX) { if ((x + y) % 2 === 0) { return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2; @@ -120,7 +121,7 @@ function medianOfTwoSortedArraysProblem() { low = partitionX + 1; } } - + throw new Error("Input arrays are not sorted."); }; @@ -131,7 +132,8 @@ function medianOfTwoSortedArraysProblem() { return (

- Input: nums1 = {"[" + nums1.join(", ") + "]"}, nums2 = {"[" + nums2.join(", ") + "]"} + Input: nums1 = {"[" + nums1.join(", ") + "]"}, nums2 ={" "} + {"[" + nums2.join(", ") + "]"}

Output: {result} @@ -143,52 +145,14 @@ function medianOfTwoSortedArraysProblem() { ### Code in Different Languages -## Python -class Solution: - def findMedianSortedArrays(self, nums1, nums2): - # Ensure nums1 is the smaller array - if len(nums1) > len(nums2): - nums1, nums2 = nums2, nums1 - - m, n = len(nums1), len(nums2) - imin, imax, half_len = 0, m, (m + n + 1) // 2 - - while imin <= imax: - i = (imin + imax) // 2 - j = half_len - i - - if i < m and nums1[i] < nums2[j - 1]: - # i is too small, must increase it - imin = i + 1 - elif i > 0 and nums1[i - 1] > nums2[j]: - # i is too big, must decrease it - imax = i - 1 - else: - # i is perfect - if i == 0: max_of_left = nums2[j - 1] - elif j == 0: max_of_left = nums1[i - 1] - else: max_of_left = max(nums1[i - 1], nums2[j - 1]) - - if (m + n) % 2 == 1: - return max_of_left - - if i == m: min_of_right = nums2[j] - elif j == n: min_of_right = nums1[i] - else: min_of_right = min(nums1[i], nums2[j]) - - return (max_of_left + min_of_right) / 2.0 - -# Example usage: -solution = Solution() -nums1 = [1, 3] -nums2 = [2] -print(solution.findMedianSortedArrays(nums1, nums2)) # Output: 2.0 + - +### JavaScript Implementation: - ```js + +```JavaScript var findMedianSortedArrays = function(nums1, nums2) { if (nums1.length > nums2.length) { [nums1, nums2] = [nums2, nums1]; @@ -223,90 +187,104 @@ print(solution.findMedianSortedArrays(nums1, nums2)) # Output: 2.0 throw new Error("Input arrays are not sorted."); }; - ``` +``` + +### Python Implementation: + - - ```python - class Solution: - def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: + +```Python + class Solution: + def findMedianSortedArrays(self, nums1, nums2): + # Ensure nums1 is the smaller array if len(nums1) > len(nums2): nums1, nums2 = nums2, nums1 - - x = len(nums1) - y = len(nums2) - low, high = 0, x - - while low <= high: - partitionX = (low + high) // 2 - partitionY = (x + y + 1) // 2 - partitionX - - maxX = float('-inf') if partitionX == 0 else nums1[partitionX - 1] - minX = float('inf') if partitionX == x else nums1[partitionX] - - maxY = float('-inf') if partitionY == 0 else nums2[partitionY - 1] - minY = float('inf') if partitionY == y else nums2[partitionY] - - if maxX <= minY and maxY <= minX: - if (x + y) % 2 == 0: - return (max(maxX, maxY) + min(minX, minY)) / 2 - else: - return max(maxX, maxY) - elif maxX > minY: - high = partitionX - 1 + + m, n = len(nums1), len(nums2) + imin, imax, half_len = 0, m, (m + n + 1) // 2 + + while imin <= imax: + i = (imin + imax) // 2 + j = half_len - i + + if i < m and nums1[i] < nums2[j - 1]: + # i is too small, must increase it + imin = i + 1 + elif i > 0 and nums1[i - 1] > nums2[j]: + # i is too big, must decrease it + imax = i - 1 else: - low = partitionX + 1 - - raise ValueError("Input arrays are not sorted.") - ``` - - - - ```java - class Solution { - public double findMedianSortedArrays(int[] nums1, int[] nums2) { - if (nums1.length > nums2.length) { - int[] temp = nums1; - nums1 = nums2; - nums2 = temp; - } + # i is perfect + if i == 0: max_of_left = nums2[j - 1] + elif j == 0: max_of_left = nums1[i - 1] + else: max_of_left = max(nums1[i - 1], nums2[j - 1]) - int x = nums1.length; - int y = nums2.length; - int low = 0, high = x; + if (m + n) % 2 == 1: + return max_of_left - while (low <= high) { - int partitionX = (low + high) / 2; - int partitionY = (x + y + 1) / 2 - partitionX; + if i == m: min_of_right = nums2[j] + elif j == n: min_of_right = nums1[i] + else: min_of_right = min(nums1[i], nums2[j]) - int maxX = (partitionX == 0) ? Integer.MIN_VALUE : nums1[partitionX - 1]; - int minX = (partitionX == x) ? Integer.MAX_VALUE : nums1[partitionX]; + return (max_of_left + min_of_right) / 2.0 +```` + - int maxY = (partitionY == 0) ? Integer.MIN_VALUE : nums2[partitionY - 1]; - int minY = (partitionY == y) ? Integer.MAX_VALUE : nums2[partitionY]; +### Java Implemnetation: + + - if (maxX <= minY && maxY <= minX) { - if ((x + y) % 2 == 0) { - return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2.0; - } else { - return Math.max(maxX, maxY); - } - } else if (maxX > minY) { - high = partitionX - 1; - } else { - low = partitionX + 1; - } - } +```Java + class Solution { + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + if (nums1.length > nums2.length) { + int[] temp = nums1; + nums1 = nums2; + nums2 = temp; + } + + int x = nums1.length; + int y = nums2.length; + int low = 0, high = x; + + while (low <= high) { + int partitionX = (low + high) / 2; + int partitionY = (x + y + 1) / 2 - partitionX; + + int maxX = (partitionX == 0) ? Integer.MIN_VALUE : nums1[partitionX - 1]; + int minX = (partitionX == x) ? Integer.MAX_VALUE : nums1[partitionX]; + + int maxY = (partitionY == 0) ? Integer.MIN_VALUE : nums2[partitionY - 1]; + int minY = (partitionY == y) ? Integer.MAX_VALUE : nums2[partitionY]; + + if (maxX <= minY && maxY <= minX) { + if ((x + y) % 2 == 0) { + return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2.0; + } else { + return Math.max(maxX, maxY); + } + } else if (maxX > minY) { + high = partitionX - 1; + } else { + low = partitionX + 1; + } + } + + throw new IllegalArgumentException("Input arrays are not sorted."); + } + } + +``` + + +### CPP Implementation: - throw new IllegalArgumentException("Input arrays are not sorted."); - } - } - ``` - - ```cpp + +````cpp class Solution { public: double findMedianSortedArrays(vector& nums1, vector& nums2) { @@ -345,10 +323,14 @@ print(solution.findMedianSortedArrays(nums1, nums2)) # Output: 2.0 } }; ``` - + + +### C Implementation: + - ```c + +```C double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { if (nums1Size > nums2Size) { int* temp = nums1; @@ -390,9 +372,12 @@ print(solution.findMedianSortedArrays(nums1, nums2)) # Output: 2.0 } ``` + +### TypeScript Implementation: + - ```ts +```ts function findMedianSortedArrays(nums1: number[], nums2: number[]): number { if (nums1.length > nums2.length) { [nums1, nums2] = [nums2, nums1]; @@ -429,6 +414,7 @@ print(solution.findMedianSortedArrays(nums1, nums2)) # Output: 2.0 } ``` + ### Complexity Analysis @@ -446,7 +432,8 @@ Let's test the solution with the sample test cases: Input: nums1 = [1, 3], nums2 = [2] Output: 2.00000 Explanation: merged array = [1, 2, 3] and median is 2. -``` +```` + ```plaintext @@ -470,11 +457,11 @@ The divide and conquer approach finds the median by recursively dividing the pro 2. If the total length of both arrays is even, find the k-th and (k+1)-th smallest elements and return their average. 3. If the total length is odd, find the k-th smallest element. 4. Define a helper function `getKth` to find the k-th smallest element in the combined array: - - Base cases: - - If one array is empty, return the k-th element from the other array. - - If k is 1, return the minimum of the first elements of both arrays. - - Recursive case: - - Divide k by 2, compare the k/2-th elements of both arrays, and discard the smaller half. + - Base cases: + - If one array is empty, return the k-th element from the other array. + - If k is 1, return the minimum of the first elements of both arrays. + - Recursive case: + - Divide k by 2, compare the k/2-th elements of both arrays, and discard the smaller half. ### Implementation and Code @@ -486,7 +473,7 @@ function medianOfTwoSortedArraysProblem() { const getKth = (nums1, nums2, k) => { const len1 = nums1.length; const len2 = nums2.length; - + if (len1 > len2) return getKth(nums2, nums1, k); if (len1 === 0) return nums2[k - 1]; if (k === 1) return Math.min(nums1[0], nums2[0]); @@ -520,7 +507,8 @@ function medianOfTwoSortedArraysProblem() { return (

- Input: nums1 = {"[" + nums1.join(", ") + "]"}, nums2 = {"[" + nums2.join(", ") + "]"} + Input: nums1 = {"[" + nums1.join(", ") + "]"}, nums2 ={" "} + {"[" + nums2.join(", ") + "]"}

Output: {result} @@ -533,9 +521,11 @@ function medianOfTwoSortedArraysProblem() { ### Code in Different Languages + - ```js + +```js var findMedianSortedArrays = function(nums1, nums2) { const getKth = (nums1, nums2, k) => { const len1 = nums1.length; @@ -565,9 +555,11 @@ function medianOfTwoSortedArraysProblem() { }; ``` + - - ```python + + +```python class Solution: def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: def getKth(nums1, nums2, k): @@ -590,13 +582,15 @@ function medianOfTwoSortedArraysProblem() { if len_combined % 2 == 1: return getKth(nums1, nums2, len_combined // 2 + 1) else: - return (getKth(nums1, nums2, len_combined // 2) + + return (getKth(nums1, nums2, len_combined // 2) + getKth(nums1, nums2, len_combined // 2 + 1)) / 2 - ``` + ``` + - ```java + +```java class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { int len1 = nums1.length; @@ -640,19 +634,20 @@ function medianOfTwoSortedArraysProblem() { } ``` + - ```cpp +```cpp class Solution { public: double findMedianSortedArrays(vector& nums1, vector& nums2) { int len1 = nums1.size(); int len2 = nums2.size(); - + if (len1 > len2) { return findMedianSortedArrays(nums2, nums1); } - + int len = len1 + len2; if (len % 2 == 1) { return getKth(nums1, nums2, len / 2 + 1); @@ -665,7 +660,7 @@ function medianOfTwoSortedArraysProblem() { int getKth(vector& nums1, vector& nums2, int k) { int len1 = nums1.size(); int len2 = nums2.size(); - + if (len1 > len2) { return getKth(nums2, nums1, k); } @@ -758,6 +753,7 @@ function medianOfTwoSortedArraysProblem() { } ``` + ### Complexity Analysis @@ -792,29 +788,33 @@ Explanation: merged array = [1, 2, 3, 4] and median is (2 + 3) / 2 = 2.5. **Note**: The binary search approach is more efficient than the divide and conquer approach as it has a better time complexity of $O(log(min(n, m)))$ compared to the divide and conquer approach. However, both approaches provide a solution to the problem of finding the median of two sorted arrays. -**Which approach is best for you?** +**Which approach is best for you?** The binary search approach is more efficient and recommended for solving the problem of finding the median of two sorted arrays. However, the divide and conquer approach is also a valid solution and can be used if needed. ::: -:::tip -When asked to find the median of two sorted arrays, a direct approach that merges the two arrays and then finds the median will work but isn't optimal. Given the problem's constraints, we can leverage the fact that the arrays are already sorted and use binary search to find the median in $$ O(\log(\min(n, m))) $$ time complexity. +:::tip +When asked to find the median of two sorted arrays, a direct approach that merges the two arrays and then finds the median will work but isn't optimal. Given the problem's constraints, we can leverage the fact that the arrays are already sorted and use binary search to find the median in $$ O(\log(\min(n, m))) $$ time complexity. The key idea is to use binary search to partition the smaller array in such a way that we can easily find the median by comparing elements around the partition. #### Detailed Explanation -1. **Ensure the Smaller Array is First**: +1. **Ensure the Smaller Array is First**: + - This step is to make sure we always perform the binary search on the smaller array, which helps us manage the partition logic more easily. Let $$ \text{nums1} $$ be the smaller array and $$ \text{nums2} $$ be the larger array. 2. **Set Up Binary Search**: + - Initialize $$ \text{low} $$ and $$ \text{high} $$ pointers for the binary search on $$ \text{nums1} $$. - We aim to partition $$ \text{nums1} $$ and $$ \text{nums2} $$ such that the left side of the combined arrays contains half of the elements, and the right side contains the other half. 3. **Partitioning the Arrays**: + - Calculate $$ \text{partitionX} $$ as the midpoint of $$ \text{nums1} $$. - - Calculate $$ \text{partitionY} $$ such that the left side of the combined arrays has the same number of elements as the right side. This can be achieved by: + - Calculate $$ \text{partitionY} $$ such that the left side of the combined arrays has the same number of elements as the right side. This can be achieved by: + $$ \text{partitionY} = \frac{(x + y + 1)}{2} - \text{partitionX} $$ @@ -822,9 +822,11 @@ The key idea is to use binary search to partition the smaller array in such a wa where $$ x $$ and $$ y $$ are the lengths of $$ \text{nums1} $$ and $$ \text{nums2} $$ respectively. 4. **Boundary Conditions**: + - Handle cases where partitions might go out of bounds. If $$ \text{partitionX} $$ is 0, it means there are no elements on the left side of $$ \text{nums1} $$. If $$ \text{partitionX} $$ is $$ x $$, it means there are no elements on the right side of $$ \text{nums1} $$. 5. **Check Valid Partition**: + - A valid partition is one where the maximum element on the left side of both partitions is less than or equal to the minimum element on the right side of both partitions: $$ \text{maxX} \leq \text{minY} \quad \text{and} \quad \text{maxY} \leq \text{minX} @@ -832,6 +834,7 @@ The key idea is to use binary search to partition the smaller array in such a wa Here, $$ \text{maxX} $$ is the largest element on the left side of $$ \text{nums1} $$, $$ \text{minX} $$ is the smallest element on the right side of $$ \text{nums1} $$, and similarly for $$ \text{nums2} $$. 6. **Calculate the Median**: + - If the total number of elements $$ (x + y) $$ is even, the median is the average of the two middle values: $$ \text{median} = \frac{\text{max(maxX, maxY)} + \text{min(minX, minY)}}{2} @@ -847,8 +850,7 @@ The key idea is to use binary search to partition the smaller array in such a wa ::: - ## References - [LeetCode Problem](https://leetcode.com/problems/median-of-two-sorted-arrays/description/) -- [GeeksforGeeks Article](https://www.geeksforgeeks.org/median-of-two-sorted-arrays/) \ No newline at end of file +- [GeeksforGeeks Article](https://www.geeksforgeeks.org/median-of-two-sorted-arrays/) From 4ec56af8431404b7c30f3c9cd7b496b878baa726 Mon Sep 17 00:00:00 2001 From: Nikita Saini Date: Sat, 8 Jun 2024 11:18:31 +0530 Subject: [PATCH 3/7] Updated 004 - Median of two sorted array Manage --- .../0004-Median-of-two-Sorted-Array.md | 108 +++++++++--------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md b/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md index 0bd5af675..a0d121b40 100644 --- a/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md +++ b/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md @@ -145,12 +145,12 @@ function medianOfTwoSortedArraysProblem() { ### Code in Different Languages - +### JavaScript Implementation: + -### JavaScript Implementation: - - + + ```JavaScript var findMedianSortedArrays = function(nums1, nums2) { @@ -188,13 +188,13 @@ function medianOfTwoSortedArraysProblem() { throw new Error("Input arrays are not sorted."); }; - + ``` -### Python Implementation: +### Python Implementation: + + - - ```Python class Solution: def findMedianSortedArrays(self, nums1, nums2): @@ -229,12 +229,13 @@ function medianOfTwoSortedArraysProblem() { else: min_of_right = min(nums1[i], nums2[j]) return (max_of_left + min_of_right) / 2.0 -```` +``` + ### Java Implemnetation: - - + + ```Java class Solution { @@ -277,14 +278,13 @@ function medianOfTwoSortedArraysProblem() { } ``` - + ### CPP Implementation: + + - - - -````cpp +```cpp class Solution { public: double findMedianSortedArrays(vector& nums1, vector& nums2) { @@ -322,13 +322,12 @@ function medianOfTwoSortedArraysProblem() { throw invalid_argument("Input arrays are not sorted."); } }; - ``` +``` -### C Implementation: - - - + ### C Implementation: + + ```C double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { @@ -370,13 +369,13 @@ function medianOfTwoSortedArraysProblem() { return -1; } - ``` - +``` + ### TypeScript Implementation: + + - - ```ts function findMedianSortedArrays(nums1: number[], nums2: number[]): number { if (nums1.length > nums2.length) { @@ -412,10 +411,8 @@ function medianOfTwoSortedArraysProblem() { throw new Error("Input arrays are not sorted."); } - ``` - - - +``` + ### Complexity Analysis @@ -433,8 +430,8 @@ Input: nums1 = [1, 3], nums2 = [2] Output: 2.00000 Explanation: merged array = [1, 2, 3] and median is 2. ```` - + ```plaintext Input: nums1 = [1, 2], nums2 = [3, 4] @@ -443,7 +440,6 @@ Explanation: merged array = [1, 2, 3, 4] and median is (2 + 3) / 2 = 2.5. ``` - @@ -522,8 +518,8 @@ function medianOfTwoSortedArraysProblem() { - - + + ```js var findMedianSortedArrays = function(nums1, nums2) { @@ -553,11 +549,12 @@ function medianOfTwoSortedArraysProblem() { getKth(nums1, nums2, Math.floor(len / 2) + 1)) / 2; } }; - ``` - - - + ``` + + + + ```python class Solution: @@ -584,11 +581,11 @@ function medianOfTwoSortedArraysProblem() { else: return (getKth(nums1, nums2, len_combined // 2) + getKth(nums1, nums2, len_combined // 2 + 1)) / 2 - ``` - +``` + - - + + ```java class Solution { @@ -632,11 +629,12 @@ function medianOfTwoSortedArraysProblem() { } } } - ``` - +``` + + + + - - ```cpp class Solution { public: @@ -719,11 +717,13 @@ function medianOfTwoSortedArraysProblem() { return getKth(nums1 + i, nums1Size - i, nums2, nums2Size, k - i); } } - ``` - - - - ```ts +``` + + + + + +```ts function findMedianSortedArrays(nums1: number[], nums2: number[]): number { const getKth = (nums1: number[], nums2: number[], k: number): number => { if (nums1.length > nums2.length) return getKth(nums2, nums1, k); @@ -751,9 +751,8 @@ function medianOfTwoSortedArraysProblem() { ); } } - ``` - - +``` + ### Complexity Analysis @@ -771,7 +770,8 @@ Let's test the solution with the sample test cases: Input: nums1 = [1, 3], nums2 = [2] Output: 2.00000 Explanation: merged array = [1, 2, 3] and median is 2. -``` +```` + ```plaintext From d640e2bb680cf9a04884435ef517f0f68801f050 Mon Sep 17 00:00:00 2001 From: Ajay Dhangar <99037494+Ajay-Dhangar@users.noreply.github.com> Date: Sat, 8 Jun 2024 13:03:22 +0530 Subject: [PATCH 4/7] solved errors --- .../0004-Median-of-two-Sorted-Array.md | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md b/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md index a0d121b40..4190dfa47 100644 --- a/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md +++ b/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md @@ -16,7 +16,7 @@ In this page, we will solve the problem [Median of Two Sorted Arrays](https://le Given two sorted arrays `nums1` and `nums2` of size `m` and `n` respectively, return the median of the two sorted arrays. -The overall run time complexity should be $O(log (m+n))$. +The overall run time complexity should be $O(log (m+n))$. ### Example 1 @@ -429,7 +429,7 @@ Let's test the solution with the sample test cases: Input: nums1 = [1, 3], nums2 = [2] Output: 2.00000 Explanation: merged array = [1, 2, 3] and median is 2. -```` +``` @@ -770,8 +770,7 @@ Let's test the solution with the sample test cases: Input: nums1 = [1, 3], nums2 = [2] Output: 2.00000 Explanation: merged array = [1, 2, 3] and median is 2. -```` - +``` ```plaintext @@ -786,7 +785,7 @@ Explanation: merged array = [1, 2, 3, 4] and median is (2 + 3) / 2 = 2.5. :::info -**Note**: The binary search approach is more efficient than the divide and conquer approach as it has a better time complexity of $O(log(min(n, m)))$ compared to the divide and conquer approach. However, both approaches provide a solution to the problem of finding the median of two sorted arrays. +**Note**: The binary search approach is more efficient than the divide and conquer approach as it has a better time complexity of $O(log(min(n, m)))$ compared to the divide and conquer approach. However, both approaches provide a solution to the problem of finding the median of two sorted arrays. **Which approach is best for you?** @@ -795,7 +794,7 @@ The binary search approach is more efficient and recommended for solving the pro ::: :::tip -When asked to find the median of two sorted arrays, a direct approach that merges the two arrays and then finds the median will work but isn't optimal. Given the problem's constraints, we can leverage the fact that the arrays are already sorted and use binary search to find the median in $$ O(\log(\min(n, m))) $$ time complexity. +When asked to find the median of two sorted arrays, a direct approach that merges the two arrays and then finds the median will work but isn't optimal. Given the problem's constraints, we can leverage the fact that the arrays are already sorted and use binary search to find the median in $O(\log(\min(n, m)))$ time complexity. The key idea is to use binary search to partition the smaller array in such a way that we can easily find the median by comparing elements around the partition. @@ -823,7 +822,7 @@ The key idea is to use binary search to partition the smaller array in such a wa 4. **Boundary Conditions**: - - Handle cases where partitions might go out of bounds. If $$ \text{partitionX} $$ is 0, it means there are no elements on the left side of $$ \text{nums1} $$. If $$ \text{partitionX} $$ is $$ x $$, it means there are no elements on the right side of $$ \text{nums1} $$. + - Handle cases where partitions might go out of bounds. If $$ \text{partitionX} $$ is 0, it means there are no elements on the left side of $$ \text{nums1} $$. If $$ \text{partitionX} $$ is $x$, it means there are no elements on the right side of $$ \text{nums1} $$. 5. **Check Valid Partition**: @@ -831,11 +830,11 @@ The key idea is to use binary search to partition the smaller array in such a wa $$ \text{maxX} \leq \text{minY} \quad \text{and} \quad \text{maxY} \leq \text{minX} $$ - Here, $$ \text{maxX} $$ is the largest element on the left side of $$ \text{nums1} $$, $$ \text{minX} $$ is the smallest element on the right side of $$ \text{nums1} $$, and similarly for $$ \text{nums2} $$. + Here, $\text{maxX}$ is the largest element on the left side of $\text{nums1}$, $\text{minX}$ is the smallest element on the right side of $\text{nums1}$, and similarly for $\text{nums2}$. 6. **Calculate the Median**: - - If the total number of elements $$ (x + y) $$ is even, the median is the average of the two middle values: + - If the total number of elements $(x + y)$ is even, the median is the average of the two middle values: $$ \text{median} = \frac{\text{max(maxX, maxY)} + \text{min(minX, minY)}}{2} $$ @@ -845,8 +844,8 @@ The key idea is to use binary search to partition the smaller array in such a wa $$ 7. **Adjust Binary Search**: - - If $$ \text{maxX} > \text{minY} $$, it means we need to move the partition in $$ \text{nums1} $$ to the left, so adjust $$ \text{high} $$. - - If $$ \text{maxY} > \text{minX} $$, it means we need to move the partition in $$ \text{nums1} $$ to the right, so adjust $$ \text{low} $$. + - If $\text{maxX} > \text{minY}$, it means we need to move the partition in $\text{nums1}$ to the left, so adjust $\text{high}$. + - If $\text{maxY} > \text{minX}$, it means we need to move the partition in $\text{nums1}$ to the right, so adjust $\text{low}$. ::: From b764e38bac013c2413a044d18e293b0215dcaee4 Mon Sep 17 00:00:00 2001 From: Nikita Saini Date: Sat, 8 Jun 2024 13:30:51 +0530 Subject: [PATCH 5/7] Implement the requested changes Implement changes requested by the author --- .../0004-Median-of-two-Sorted-Array.md | 535 ++++++++---------- 1 file changed, 251 insertions(+), 284 deletions(-) diff --git a/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md b/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md index a0d121b40..2168ddb42 100644 --- a/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md +++ b/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md @@ -7,7 +7,7 @@ tags: - Binary Search - Divide and Conquer0 - LeetCode -description: Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. The overall run time complexity should be $O(log (m+n))$. +description: Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. --- In this page, we will solve the problem [Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/description/) from LeetCode. We will provide multiple approaches to solve the problem along with the code implementation and the complexity analysis of the code. @@ -16,7 +16,7 @@ In this page, we will solve the problem [Median of Two Sorted Arrays](https://le Given two sorted arrays `nums1` and `nums2` of size `m` and `n` respectively, return the median of the two sorted arrays. -The overall run time complexity should be $O(log (m+n))$. +The overall run time complexity should be $O(log (m+n))$. ### Example 1 @@ -192,6 +192,7 @@ function medianOfTwoSortedArraysProblem() { ``` ### Python Implementation: + @@ -234,6 +235,7 @@ function medianOfTwoSortedArraysProblem() { ### Java Implemnetation: + @@ -278,54 +280,67 @@ function medianOfTwoSortedArraysProblem() { } ``` + ### CPP Implementation: + ```cpp - class Solution { - public: - double findMedianSortedArrays(vector& nums1, vector& nums2) { - if (nums1.size() > nums2.size()) { - swap(nums1, nums2); - } + class Solution { +public: + double findMedianSortedArrays(vector& nums1, vector& nums2) { + int len1 = nums1.size(); + int len2 = nums2.size(); - int x = nums1.size(); - int y = nums2.size(); - int low = 0, high = x; + if (len1 > len2) { + return findMedianSortedArrays(nums2, nums1); + } - while (low <= high) { - int partitionX = (low + high) / 2; - int partitionY = (x + y + 1) / 2 - partitionX; + int len = len1 + len2; + if (len % 2 == 1) { + return getKth(nums1, nums2, len / 2 + 1); + } else { + return (getKth(nums1, nums2, len / 2) + getKth(nums1, nums2, len / 2 + 1)) / 2.0; + } + } - int maxX = (partitionX == 0) ? INT_MIN : nums1[partitionX - 1]; - int minX = (partitionX == x) ? INT_MAX : nums1[partitionX]; +private: + int getKth(vector& nums1, vector& nums2, int k) { + int len1 = nums1.size(); + int len2 = nums2.size(); - int maxY = (partitionY == 0) ? INT_MIN : nums2[partitionY - 1]; - int minY = (partitionY == y) ? INT_MAX : nums2[partitionY]; + if (len1 > len2) { + return getKth(nums2, nums1, k); + } + if (len1 == 0) { + return nums2[k - 1]; + } + if (k == 1) { + return min(nums1[0], nums2[0]); + } - if (maxX <= minY && maxY <= minX) { - if ((x + y) % 2 == 0) { - return (max(maxX, maxY) + min(minX, minY)) / 2.0; - } else { - return max(maxX, maxY); - } - } else if (maxX > minY) { - high = partitionX - 1; - } else { - low = partitionX + 1; - } - } + int i = min(len1, k / 2); + int j = min(len2, k / 2); - throw invalid_argument("Input arrays are not sorted."); + if (nums1[i - 1] > nums2[j - 1]) { + vector nums2New(nums2.begin() + j, nums2.end()); + return getKth(nums1, nums2New, k - j); + } else { + vector nums1New(nums1.begin() + i, nums1.end()); + return getKth(nums1New, nums2, k - i); } - }; + } +}; + ``` + - ### C Implementation: +### C Implementation: + @@ -370,49 +385,54 @@ function medianOfTwoSortedArraysProblem() { return -1; } ``` + ### TypeScript Implementation: + ```ts - function findMedianSortedArrays(nums1: number[], nums2: number[]): number { - if (nums1.length > nums2.length) { - [nums1, nums2] = [nums2, nums1]; - } +function findMedianSortedArrays(nums1: number[], nums2: number[]): number { + if (nums1.length > nums2.length) { + [nums1, nums2] = [nums2, nums1]; + } - let x = nums1.length; - let y = nums2.length; - let low = 0, high = x; + let x = nums1.length; + let y = nums2.length; + let low = 0, + high = x; - while (low <= high) { - let partitionX = Math.floor((low + high) / 2); - let partitionY = Math.floor((x + y + 1) / 2) - partitionX; + while (low <= high) { + let partitionX = Math.floor((low + high) / 2); + let partitionY = Math.floor((x + y + 1) / 2) - partitionX; - let maxX = (partitionX === 0) ? -Infinity : nums1[partitionX - 1]; - let minX = (partitionX === x) ? Infinity : nums1[partitionX]; + let maxX = partitionX === 0 ? -Infinity : nums1[partitionX - 1]; + let minX = partitionX === x ? Infinity : nums1[partitionX]; - let maxY = (partitionY === 0) ? -Infinity : nums2[partitionY - 1]; - let minY = (partitionY === y) ? Infinity : nums2[partitionY]; - - if (maxX <= minY && maxY <= minX) { - if ((x + y) % 2 === 0) { - return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2; - } else { - return Math.max(maxX, maxY); - } - } else if (maxX > minY) { - high = partitionX - 1; - } else { - low = partitionX + 1; - } - } + let maxY = partitionY === 0 ? -Infinity : nums2[partitionY - 1]; + let minY = partitionY === y ? Infinity : nums2[partitionY]; - throw new Error("Input arrays are not sorted."); + if (maxX <= minY && maxY <= minX) { + if ((x + y) % 2 === 0) { + return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2; + } else { + return Math.max(maxX, maxY); + } + } else if (maxX > minY) { + high = partitionX - 1; + } else { + low = partitionX + 1; } + } + + throw new Error("Input arrays are not sorted."); +} ``` + + ### Complexity Analysis @@ -442,248 +462,194 @@ Explanation: merged array = [1, 2, 3, 4] and median is (2 + 3) / 2 = 2.5. - -## Approach 2: Divide and Conquer + + +ChatGPT + +### Approach 2: Divide and Conquer The divide and conquer approach finds the median by recursively dividing the problem into smaller subproblems. It merges two sorted arrays by comparing and removing the smallest element from the two arrays until the median is found. ### Pseudocode -1. Ensure `nums1` is the smaller array. -2. If the total length of both arrays is even, find the k-th and (k+1)-th smallest elements and return their average. -3. If the total length is odd, find the k-th smallest element. -4. Define a helper function `getKth` to find the k-th smallest element in the combined array: - - Base cases: - - If one array is empty, return the k-th element from the other array. - - If k is 1, return the minimum of the first elements of both arrays. - - Recursive case: - - Divide k by 2, compare the k/2-th elements of both arrays, and discard the smaller half. +- Ensure nums1 is the smaller array. +- If the total length of both arrays is even, find the k-th and (k+1)-th smallest elements and return their average. +- If the total length is odd, find the k-th smallest element. +- Define a helper function getKth to find the k-th smallest element in the combined array: +- Base cases: +- If one array is empty, return the k-th element from the other array. +- If k is 1, return the minimum of the first elements of both arrays. +- Recursive case: +- Divide k by 2, compare the k/2-th elements of both arrays, and discard the smaller half. ### Implementation and Code -Here is a live code editor for you to play around with the solution: +Here is the implementation of the divide and conquer approach in various languages: -```jsx live -function medianOfTwoSortedArraysProblem() { - const findMedianSortedArrays = (nums1, nums2) => { - const getKth = (nums1, nums2, k) => { - const len1 = nums1.length; - const len2 = nums2.length; +### JavaScript Implementation: - if (len1 > len2) return getKth(nums2, nums1, k); - if (len1 === 0) return nums2[k - 1]; - if (k === 1) return Math.min(nums1[0], nums2[0]); +```jsx live +var findMedianSortedArrays = function (nums1, nums2) { + const getKth = (nums1, nums2, k) => { + const len1 = nums1.length; + const len2 = nums2.length; - const i = Math.min(len1, Math.floor(k / 2)); - const j = Math.min(len2, Math.floor(k / 2)); + if (len1 > len2) return getKth(nums2, nums1, k); + if (len1 === 0) return nums2[k - 1]; + if (k === 1) return Math.min(nums1[0], nums2[0]); - if (nums1[i - 1] > nums2[j - 1]) { - return getKth(nums1, nums2.slice(j), k - j); - } else { - return getKth(nums1.slice(i), nums2, k - i); - } - }; + const i = Math.min(len1, Math.floor(k / 2)); + const j = Math.min(len2, Math.floor(k / 2)); - const len = nums1.length + nums2.length; - if (len % 2 === 1) { - return getKth(nums1, nums2, Math.floor(len / 2) + 1); + if (nums1[i - 1] > nums2[j - 1]) { + return getKth(nums1, nums2.slice(j), k - j); } else { - return ( - (getKth(nums1, nums2, Math.floor(len / 2)) + - getKth(nums1, nums2, Math.floor(len / 2) + 1)) / - 2 - ); + return getKth(nums1.slice(i), nums2, k - i); } }; - const nums1 = [1, 3]; - const nums2 = [2]; - const result = findMedianSortedArrays(nums1, nums2); - - return ( -

-

- Input: nums1 = {"[" + nums1.join(", ") + "]"}, nums2 ={" "} - {"[" + nums2.join(", ") + "]"} -

-

- Output: {result} -

-
- ); -} + const len = nums1.length + nums2.length; + if (len % 2 === 1) { + return getKth(nums1, nums2, Math.floor(len / 2) + 1); + } else { + return ( + (getKth(nums1, nums2, Math.floor(len / 2)) + + getKth(nums1, nums2, Math.floor(len / 2) + 1)) / + 2 + ); + } +}; ``` -### Code in Different Languages +### Python Implementation: - +```python +class Solution: + def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: + def getKth(nums1, nums2, k): + if len(nums1) > len(nums2): + return getKth(nums2, nums1, k) + if len(nums1) == 0: + return nums2[k - 1] + if k == 1: + return min(nums1[0], nums2[0]) - - + i = min(len(nums1), k // 2) + j = min(len(nums2), k // 2) -```js - var findMedianSortedArrays = function(nums1, nums2) { - const getKth = (nums1, nums2, k) => { - const len1 = nums1.length; - const len2 = nums2.length; + if nums1[i - 1] > nums2[j - 1]: + return getKth(nums1, nums2[j:], k - j) + else: + return getKth(nums1[i:], nums2, k - i) + + len_combined = len(nums1) + len(nums2) + if len_combined % 2 == 1: + return getKth(nums1, nums2, len_combined // 2 + 1) + else: + return (getKth(nums1, nums2, len_combined // 2) + + getKth(nums1, nums2, len_combined // 2 + 1)) / 2 +``` - if (len1 > len2) return getKth(nums2, nums1, k); - if (len1 === 0) return nums2[k - 1]; - if (k === 1) return Math.min(nums1[0], nums2[0]); +### Java Implementation: - const i = Math.min(len1, Math.floor(k / 2)); - const j = Math.min(len2, Math.floor(k / 2)); +```java +class Solution { + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + int len1 = nums1.length; + int len2 = nums2.length; - if (nums1[i - 1] > nums2[j - 1]) { - return getKth(nums1, nums2.slice(j), k - j); - } else { - return getKth(nums1.slice(i), nums2, k - i); - } - }; + if (len1 > len2) { + return findMedianSortedArrays(nums2, nums1); + } - const len = nums1.length + nums2.length; - if (len % 2 === 1) { - return getKth(nums1, nums2, Math.floor(len / 2) + 1); + int len = len1 + len2; + if (len % 2 == 1) { + return getKth(nums1, nums2, len / 2 + 1); } else { - return (getKth(nums1, nums2, Math.floor(len / 2)) + - getKth(nums1, nums2, Math.floor(len / 2) + 1)) / 2; + return (getKth(nums1, nums2, len / 2) + getKth(nums1, nums2, len / 2 + 1)) / 2.0; } - }; + } - ``` - - - - + private int getKth(int[] nums1, int[] nums2, int k) { + int len1 = nums1.length; + int len2 = nums2.length; -```python - class Solution: - def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: - def getKth(nums1, nums2, k): - if len(nums1) > len(nums2): - return getKth(nums2, nums1, k) - if len(nums1) == 0: - return nums2[k - 1] - if k == 1: - return min(nums1[0], nums2[0]) - - i = min(len(nums1), k // 2) - j = min(len(nums2), k // 2) - - if nums1[i - 1] > nums2[j - 1]: - return getKth(nums1, nums2[j:], k - j) - else: - return getKth(nums1[i:], nums2, k - i) + if (len1 > len2) { + return getKth(nums2, nums1, k); + } + if (len1 == 0) { + return nums2[k - 1]; + } + if (k == 1) { + return Math.min(nums1[0], nums2[0]); + } - len_combined = len(nums1) + len(nums2) - if len_combined % 2 == 1: - return getKth(nums1, nums2, len_combined // 2 + 1) - else: - return (getKth(nums1, nums2, len_combined // 2) + - getKth(nums1, nums2, len_combined // 2 + 1)) / 2 + int i = Math.min(len1, k / 2); + int j = Math.min(len2, k / 2); + + if (nums1[i - 1] > nums2[j - 1]) { + return getKth(nums1, Arrays.copyOfRange(nums2, j, len2), k - j); + } else { + return getKth(Arrays.copyOfRange(nums1, i, len1), nums2, k - i); + } + } +} ``` - - - +### C++ Implementation: -```java - class Solution { - public double findMedianSortedArrays(int[] nums1, int[] nums2) { - int len1 = nums1.length; - int len2 = nums2.length; +```c++ +class Solution { +public: + double findMedianSortedArrays(vector& nums1, vector& nums2) { + int len1 = nums1.size(); + int len2 = nums2.size(); - if (len1 > len2) { - return findMedianSortedArrays(nums2, nums1); - } + if (len1 > len2) { + return findMedianSortedArrays(nums2, nums1); + } - int len = len1 + len2; - if (len % 2 == 1) { - return getKth(nums1, nums2, len / 2 + 1); - } else { - return (getKth(nums1, nums2, len / 2) + getKth(nums1, nums2, len / 2 + 1)) / 2.0; - } + int len = len1 + len2; + if (len % 2 == 1) { + return getKth(nums1, nums2, len / 2 + 1); + } else { + return (getKth(nums1, nums2, len / 2) + getKth(nums1, nums2, len / 2 + 1)) / 2.0; } + } - private int getKth(int[] nums1, int[] nums2, int k) { - int len1 = nums1.length; - int len2 = nums2.length; +private: + int getKth(vector& nums1, vector& nums2, int k) { + int len1 = nums1.size(); + int len2 = nums2.size(); - if (len1 > len2) { - return getKth(nums2, nums1, k); - } - if (len1 == 0) { - return nums2[k - 1]; - } - if (k == 1) { - return Math.min(nums1[0], nums2[0]); - } + if (len1 > len2) { + return getKth(nums2, nums1, k); + } + if (len1 == 0) { + return nums2[k - 1]; + } + if (k == 1) { + return min(nums1[0], nums2[0]); + } - int i = Math.min(len1, k / 2); - int j = Math.min(len2, k / 2); + int i = min(len1, k / 2); + int j = min(len2, k / 2); - if (nums1[i - 1] > nums2[j - 1]) { - return getKth(nums1, Arrays.copyOfRange(nums2, j, len2), k - j); - } else { - return getKth(Arrays.copyOfRange(nums1, i, len1), nums2, k - i); - } + if (nums1[i - 1] > nums2[j - 1]) { + return getKth(nums1, vector(nums2.begin() + j, nums2.end()), k - j); + } else { + return getKth(vector(nums1.begin() + i, nums1.end()), nums2, k - i); } } +}; ``` - - - - - -```cpp - class Solution { - public: - double findMedianSortedArrays(vector& nums1, vector& nums2) { - int len1 = nums1.size(); - int len2 = nums2.size(); - - if (len1 > len2) { - return findMedianSortedArrays(nums2, nums1); - } - - int len = len1 + len2; - if (len % 2 == 1) { - return getKth(nums1, nums2, len / 2 + 1); - } else { - return (getKth(nums1, nums2, len / 2) + getKth(nums1, nums2, len / 2 + 1)) / 2.0; - } - } - private: - int getKth(vector& nums1, vector& nums2, int k) { - int len1 = nums1.size(); - int len2 = nums2.size(); +### C Implementation: - if (len1 > len2) { - return getKth(nums2, nums1, k); - } - if (len 1 == 0) { - return nums2[k - 1]; - } - if (k == 1) { - return min(nums1[0], nums2[0]); - } - - int i = min(len1, k / 2); - int j = min(len2, k / 2); + + - if (nums1[i - 1] > nums2[j - 1]) { - return getKth(nums1, vector(nums2.begin() + j, nums2.end()), k - j); - } else { - return getKth(vector(nums1.begin() + i, nums1.end()), nums2, k - i); - } - } - }; - ``` - - - - ```c +```c double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { if (nums1Size > nums2Size) { return findMedianSortedArrays(nums2, nums2Size, nums1, nums1Size); @@ -718,40 +684,42 @@ function medianOfTwoSortedArraysProblem() { } } ``` + ```ts - function findMedianSortedArrays(nums1: number[], nums2: number[]): number { - const getKth = (nums1: number[], nums2: number[], k: number): number => { - if (nums1.length > nums2.length) return getKth(nums2, nums1, k); - if (nums1.length === 0) return nums2[k - 1]; - if (k === 1) return Math.min(nums1[0], nums2[0]); +function findMedianSortedArrays(nums1: number[], nums2: number[]): number { + const getKth = (nums1: number[], nums2: number[], k: number): number => { + if (nums1.length > nums2.length) return getKth(nums2, nums1, k); + if (nums1.length === 0) return nums2[k - 1]; + if (k === 1) return Math.min(nums1[0], nums2[0]); - const i = Math.min(nums1.length, Math.floor(k / 2)); - const j = Math.min(nums2.length, Math.floor(k / 2)); + const i = Math.min(nums1.length, Math.floor(k / 2)); + const j = Math.min(nums2.length, Math.floor(k / 2)); - if (nums1[i - 1] > nums2[j - 1]) { - return getKth(nums1, nums2.slice(j), k - j); - } else { - return getKth(nums1.slice(i), nums2, k - i); - } - }; - - const len = nums1.length + nums2.length; - if (len % 2 === 1) { - return getKth(nums1, nums2, Math.floor(len / 2) + 1); - } else { - return ( - (getKth(nums1, nums2, Math.floor(len / 2)) + - getKth(nums1, nums2, Math.floor(len / 2) + 1)) / - 2 - ); - } + if (nums1[i - 1] > nums2[j - 1]) { + return getKth(nums1, nums2.slice(j), k - j); + } else { + return getKth(nums1.slice(i), nums2, k - i); } + }; + + const len = nums1.length + nums2.length; + if (len % 2 === 1) { + return getKth(nums1, nums2, Math.floor(len / 2) + 1); + } else { + return ( + (getKth(nums1, nums2, Math.floor(len / 2)) + + getKth(nums1, nums2, Math.floor(len / 2) + 1)) / + 2 + ); + } +} ``` + @@ -782,11 +750,10 @@ Explanation: merged array = [1, 2, 3, 4] and median is (2 + 3) / 2 = 2.5. - :::info -**Note**: The binary search approach is more efficient than the divide and conquer approach as it has a better time complexity of $O(log(min(n, m)))$ compared to the divide and conquer approach. However, both approaches provide a solution to the problem of finding the median of two sorted arrays. +**Note**: The binary search approach is more efficient than the divide and conquer approach as it has a better time complexity of $O(log(min(n, m)))$ compared to the divide and conquer approach. However, both approaches provide a solution to the problem of finding the median of two sorted arrays. **Which approach is best for you?** @@ -795,7 +762,7 @@ The binary search approach is more efficient and recommended for solving the pro ::: :::tip -When asked to find the median of two sorted arrays, a direct approach that merges the two arrays and then finds the median will work but isn't optimal. Given the problem's constraints, we can leverage the fact that the arrays are already sorted and use binary search to find the median in $$ O(\log(\min(n, m))) $$ time complexity. +When asked to find the median of two sorted arrays, a direct approach that merges the two arrays and then finds the median will work but isn't optimal. Given the problem's constraints, we can leverage the fact that the arrays are already sorted and use binary search to find the median in $O(\log(\min(n, m)))$ time complexity. The key idea is to use binary search to partition the smaller array in such a way that we can easily find the median by comparing elements around the partition. @@ -835,7 +802,7 @@ The key idea is to use binary search to partition the smaller array in such a wa 6. **Calculate the Median**: - - If the total number of elements $$ (x + y) $$ is even, the median is the average of the two middle values: + - If the total number of elements $ (x + y) $ is even, the median is the average of the two middle values: $$ \text{median} = \frac{\text{max(maxX, maxY)} + \text{min(minX, minY)}}{2} $$ From 365985535a8e0f76ef4033227a9ab46333845a08 Mon Sep 17 00:00:00 2001 From: Ajay Dhangar <99037494+Ajay-Dhangar@users.noreply.github.com> Date: Sat, 8 Jun 2024 16:43:51 +0530 Subject: [PATCH 6/7] Update 0004-Median-of-two-Sorted-Array.md --- .../0004-Median-of-two-Sorted-Array.md | 846 +++++++++--------- 1 file changed, 419 insertions(+), 427 deletions(-) diff --git a/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md b/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md index 2bff3de08..4c3e85bb2 100644 --- a/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md +++ b/dsa-solutions/lc-solutions/0000-0099/0004-Median-of-two-Sorted-Array.md @@ -2,19 +2,21 @@ id: median-of-two-sorted-arrays title: Median of Two Sorted Arrays(Leetcode) sidebar_label: 0004 - Median of Two Sorted Arrays -tags: - - Array - - Binary Search - - Divide and Conquer0 - - LeetCode -description: Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. +tags: + - Array + - Binary Search + - Divide and Conquer0 + - LeetCode +description: Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. The overall run time complexity should be $O(log (m+n))$. --- In this page, we will solve the problem [Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/description/) from LeetCode. We will provide multiple approaches to solve the problem along with the code implementation and the complexity analysis of the code. ## Problem Statement -Given two sorted arrays `nums1` and `nums2` of size `m` and `n` respectively, return the median of the two sorted arrays. +Given two sorted arrays `nums1` and `nums2` of size `m` and `n` respectively, return the median of the two sorted arrays. + +The overall run time complexity should be $O(log (m+n))$. ### Example 1 @@ -45,7 +47,7 @@ Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5. ## Solution for Median of Two Sorted Arrays -The **Median of Two Sorted Arrays** is a classic algorithm problem on LeetCode ([Problem 4](https://leetcode.com/problems/median-of-two-sorted-arrays/description/)). It requires finding the median of two sorted arrays. Given two sorted arrays `nums1` and `nums2`, the task is to find the median of the two arrays combined. +The **Median of Two Sorted Arrays** is a classic algorithm problem on LeetCode ([Problem 4](https://leetcode.com/problems/median-of-two-sorted-arrays/description/)). It requires finding the median of two sorted arrays. Given two sorted arrays `nums1` and `nums2`, the task is to find the median of the two arrays combined. Here is an explanation of the intuition and approaches to solve this problem: @@ -67,17 +69,17 @@ The binary search approach involves partitioning the two arrays such that the co 1. Ensure `nums1` is the smaller array. 2. Initialize `low` and `high` for binary search on `nums1`. 3. While `low <= high`: - - Calculate `partitionX` and `partitionY`. - - Set `maxX`, `minX`, `maxY`, `minY`. - - If `maxX <= minY` and `maxY <= minX`: - - If total number of elements is even - - Return average of `max(maxX, maxY)` and `min(minX, minY)`. - - Else - - Return `max(maxX, maxY)`. - - If `maxX > minY`: - - Move `high` to `partitionX - 1`. - - Else: - - Move `low` to `partitionX + 1`. + - Calculate `partitionX` and `partitionY`. + - Set `maxX`, `minX`, `maxY`, `minY`. + - If `maxX <= minY` and `maxY <= minX`: + - If total number of elements is even + - Return average of `max(maxX, maxY)` and `min(minX, minY)`. + - Else + - Return `max(maxX, maxY)`. + - If `maxX > minY`: + - Move `high` to `partitionX - 1`. + - Else: + - Move `low` to `partitionX + 1`. 4. If no median is found, raise an error. ### Implementation and Code @@ -91,22 +93,21 @@ function medianOfTwoSortedArraysProblem() { if (nums1.length > nums2.length) { [nums1, nums2] = [nums2, nums1]; } - + const x = nums1.length; const y = nums2.length; - let low = 0, - high = x; - + let low = 0, high = x; + while (low <= high) { const partitionX = Math.floor((low + high) / 2); const partitionY = Math.floor((x + y + 1) / 2) - partitionX; - - const maxX = partitionX === 0 ? -Infinity : nums1[partitionX - 1]; - const minX = partitionX === x ? Infinity : nums1[partitionX]; - - const maxY = partitionY === 0 ? -Infinity : nums2[partitionY - 1]; - const minY = partitionY === y ? Infinity : nums2[partitionY]; - + + const maxX = (partitionX === 0) ? -Infinity : nums1[partitionX - 1]; + const minX = (partitionX === x) ? Infinity : nums1[partitionX]; + + const maxY = (partitionY === 0) ? -Infinity : nums2[partitionY - 1]; + const minY = (partitionY === y) ? Infinity : nums2[partitionY]; + if (maxX <= minY && maxY <= minX) { if ((x + y) % 2 === 0) { return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2; @@ -119,7 +120,7 @@ function medianOfTwoSortedArraysProblem() { low = partitionX + 1; } } - + throw new Error("Input arrays are not sorted."); }; @@ -130,8 +131,7 @@ function medianOfTwoSortedArraysProblem() { return (

- Input: nums1 = {"[" + nums1.join(", ") + "]"}, nums2 ={" "} - {"[" + nums2.join(", ") + "]"} + Input: nums1 = {"[" + nums1.join(", ") + "]"}, nums2 = {"[" + nums2.join(", ") + "]"}

Output: {result} @@ -143,14 +143,10 @@ function medianOfTwoSortedArraysProblem() { ### Code in Different Languages -### JavaScript Implementation: - - - - - -```JavaScript + + + ```js var findMedianSortedArrays = function(nums1, nums2) { if (nums1.length > nums2.length) { [nums1, nums2] = [nums2, nums1]; @@ -185,164 +181,132 @@ function medianOfTwoSortedArraysProblem() { throw new Error("Input arrays are not sorted."); }; - - -``` - -### Python Implementation: - - - - -```Python - class Solution: - def findMedianSortedArrays(self, nums1, nums2): - # Ensure nums1 is the smaller array + ``` + + + + + ```python + class Solution: + def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: if len(nums1) > len(nums2): nums1, nums2 = nums2, nums1 - - m, n = len(nums1), len(nums2) - imin, imax, half_len = 0, m, (m + n + 1) // 2 - - while imin <= imax: - i = (imin + imax) // 2 - j = half_len - i - - if i < m and nums1[i] < nums2[j - 1]: - # i is too small, must increase it - imin = i + 1 - elif i > 0 and nums1[i - 1] > nums2[j]: - # i is too big, must decrease it - imax = i - 1 + + x = len(nums1) + y = len(nums2) + low, high = 0, x + + while low <= high: + partitionX = (low + high) // 2 + partitionY = (x + y + 1) // 2 - partitionX + + maxX = float('-inf') if partitionX == 0 else nums1[partitionX - 1] + minX = float('inf') if partitionX == x else nums1[partitionX] + + maxY = float('-inf') if partitionY == 0 else nums2[partitionY - 1] + minY = float('inf') if partitionY == y else nums2[partitionY] + + if maxX <= minY and maxY <= minX: + if (x + y) % 2 == 0: + return (max(maxX, maxY) + min(minX, minY)) / 2 + else: + return max(maxX, maxY) + elif maxX > minY: + high = partitionX - 1 else: - # i is perfect - if i == 0: max_of_left = nums2[j - 1] - elif j == 0: max_of_left = nums1[i - 1] - else: max_of_left = max(nums1[i - 1], nums2[j - 1]) - - if (m + n) % 2 == 1: - return max_of_left - - if i == m: min_of_right = nums2[j] - elif j == n: min_of_right = nums1[i] - else: min_of_right = min(nums1[i], nums2[j]) - - return (max_of_left + min_of_right) / 2.0 -``` - - - -### Java Implemnetation: - - - - -```Java - class Solution { - public double findMedianSortedArrays(int[] nums1, int[] nums2) { - if (nums1.length > nums2.length) { - int[] temp = nums1; - nums1 = nums2; - nums2 = temp; - } - - int x = nums1.length; - int y = nums2.length; - int low = 0, high = x; - - while (low <= high) { - int partitionX = (low + high) / 2; - int partitionY = (x + y + 1) / 2 - partitionX; - - int maxX = (partitionX == 0) ? Integer.MIN_VALUE : nums1[partitionX - 1]; - int minX = (partitionX == x) ? Integer.MAX_VALUE : nums1[partitionX]; - - int maxY = (partitionY == 0) ? Integer.MIN_VALUE : nums2[partitionY - 1]; - int minY = (partitionY == y) ? Integer.MAX_VALUE : nums2[partitionY]; - - if (maxX <= minY && maxY <= minX) { - if ((x + y) % 2 == 0) { - return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2.0; - } else { - return Math.max(maxX, maxY); - } - } else if (maxX > minY) { - high = partitionX - 1; - } else { - low = partitionX + 1; - } - } - - throw new IllegalArgumentException("Input arrays are not sorted."); - } - } - -``` + low = partitionX + 1 + + raise ValueError("Input arrays are not sorted.") + ``` + + + + ```java + class Solution { + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + if (nums1.length > nums2.length) { + int[] temp = nums1; + nums1 = nums2; + nums2 = temp; + } - + int x = nums1.length; + int y = nums2.length; + int low = 0, high = x; -### CPP Implementation: + while (low <= high) { + int partitionX = (low + high) / 2; + int partitionY = (x + y + 1) / 2 - partitionX; - - + int maxX = (partitionX == 0) ? Integer.MIN_VALUE : nums1[partitionX - 1]; + int minX = (partitionX == x) ? Integer.MAX_VALUE : nums1[partitionX]; -```cpp - class Solution { -public: - double findMedianSortedArrays(vector& nums1, vector& nums2) { - int len1 = nums1.size(); - int len2 = nums2.size(); + int maxY = (partitionY == 0) ? Integer.MIN_VALUE : nums2[partitionY - 1]; + int minY = (partitionY == y) ? Integer.MAX_VALUE : nums2[partitionY]; - if (len1 > len2) { - return findMedianSortedArrays(nums2, nums1); - } + if (maxX <= minY && maxY <= minX) { + if ((x + y) % 2 == 0) { + return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2.0; + } else { + return Math.max(maxX, maxY); + } + } else if (maxX > minY) { + high = partitionX - 1; + } else { + low = partitionX + 1; + } + } - int len = len1 + len2; - if (len % 2 == 1) { - return getKth(nums1, nums2, len / 2 + 1); - } else { - return (getKth(nums1, nums2, len / 2) + getKth(nums1, nums2, len / 2 + 1)) / 2.0; + throw new IllegalArgumentException("Input arrays are not sorted."); } } + ``` + + + + ```cpp + class Solution { + public: + double findMedianSortedArrays(vector& nums1, vector& nums2) { + if (nums1.size() > nums2.size()) { + swap(nums1, nums2); + } -private: - int getKth(vector& nums1, vector& nums2, int k) { - int len1 = nums1.size(); - int len2 = nums2.size(); - - if (len1 > len2) { - return getKth(nums2, nums1, k); - } - if (len1 == 0) { - return nums2[k - 1]; - } - if (k == 1) { - return min(nums1[0], nums2[0]); - } - - int i = min(len1, k / 2); - int j = min(len2, k / 2); + int x = nums1.size(); + int y = nums2.size(); + int low = 0, high = x; - if (nums1[i - 1] > nums2[j - 1]) { - vector nums2New(nums2.begin() + j, nums2.end()); - return getKth(nums1, nums2New, k - j); - } else { - vector nums1New(nums1.begin() + i, nums1.end()); - return getKth(nums1New, nums2, k - i); - } - } -}; - -``` + while (low <= high) { + int partitionX = (low + high) / 2; + int partitionY = (x + y + 1) / 2 - partitionX; - + int maxX = (partitionX == 0) ? INT_MIN : nums1[partitionX - 1]; + int minX = (partitionX == x) ? INT_MAX : nums1[partitionX]; -### C Implementation: + int maxY = (partitionY == 0) ? INT_MIN : nums2[partitionY - 1]; + int minY = (partitionY == y) ? INT_MAX : nums2[partitionY]; - - + if (maxX <= minY && maxY <= minX) { + if ((x + y) % 2 == 0) { + return (max(maxX, maxY) + min(minX, minY)) / 2.0; + } else { + return max(maxX, maxY); + } + } else if (maxX > minY) { + high = partitionX - 1; + } else { + low = partitionX + 1; + } + } -```C + throw invalid_argument("Input arrays are not sorted."); + } + }; + ``` + + + + ```c double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { if (nums1Size > nums2Size) { int* temp = nums1; @@ -382,54 +346,47 @@ private: return -1; } -``` - - - -### TypeScript Implementation: - - - + ``` + + + + ```ts + function findMedianSortedArrays(nums1: number[], nums2: number[]): number { + if (nums1.length > nums2.length) { + [nums1, nums2] = [nums2, nums1]; + } -```ts -function findMedianSortedArrays(nums1: number[], nums2: number[]): number { - if (nums1.length > nums2.length) { - [nums1, nums2] = [nums2, nums1]; - } + let x = nums1.length; + let y = nums2.length; + let low = 0, high = x; - let x = nums1.length; - let y = nums2.length; - let low = 0, - high = x; + while (low <= high) { + let partitionX = Math.floor((low + high) / 2); + let partitionY = Math.floor((x + y + 1) / 2) - partitionX; - while (low <= high) { - let partitionX = Math.floor((low + high) / 2); - let partitionY = Math.floor((x + y + 1) / 2) - partitionX; + let maxX = (partitionX === 0) ? -Infinity : nums1[partitionX - 1]; + let minX = (partitionX === x) ? Infinity : nums1[partitionX]; - let maxX = partitionX === 0 ? -Infinity : nums1[partitionX - 1]; - let minX = partitionX === x ? Infinity : nums1[partitionX]; + let maxY = (partitionY === 0) ? -Infinity : nums2[partitionY - 1]; + let minY = (partitionY === y) ? Infinity : nums2[partitionY]; - let maxY = partitionY === 0 ? -Infinity : nums2[partitionY - 1]; - let minY = partitionY === y ? Infinity : nums2[partitionY]; + if (maxX <= minY && maxY <= minX) { + if ((x + y) % 2 === 0) { + return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2; + } else { + return Math.max(maxX, maxY); + } + } else if (maxX > minY) { + high = partitionX - 1; + } else { + low = partitionX + 1; + } + } - if (maxX <= minY && maxY <= minX) { - if ((x + y) % 2 === 0) { - return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2; - } else { - return Math.max(maxX, maxY); - } - } else if (maxX > minY) { - high = partitionX - 1; - } else { - low = partitionX + 1; + throw new Error("Input arrays are not sorted."); } - } - - throw new Error("Input arrays are not sorted."); -} -``` - - + ``` + ### Complexity Analysis @@ -449,7 +406,6 @@ Output: 2.00000 Explanation: merged array = [1, 2, 3] and median is 2. ``` - ```plaintext Input: nums1 = [1, 2], nums2 = [3, 4] @@ -458,196 +414,241 @@ Explanation: merged array = [1, 2, 3, 4] and median is (2 + 3) / 2 = 2.5. ``` + - - -ChatGPT - -### Approach 2: Divide and Conquer + +## Approach 2: Divide and Conquer The divide and conquer approach finds the median by recursively dividing the problem into smaller subproblems. It merges two sorted arrays by comparing and removing the smallest element from the two arrays until the median is found. ### Pseudocode -- Ensure nums1 is the smaller array. -- If the total length of both arrays is even, find the k-th and (k+1)-th smallest elements and return their average. -- If the total length is odd, find the k-th smallest element. -- Define a helper function getKth to find the k-th smallest element in the combined array: -- Base cases: -- If one array is empty, return the k-th element from the other array. -- If k is 1, return the minimum of the first elements of both arrays. -- Recursive case: -- Divide k by 2, compare the k/2-th elements of both arrays, and discard the smaller half. +1. Ensure `nums1` is the smaller array. +2. If the total length of both arrays is even, find the k-th and (k+1)-th smallest elements and return their average. +3. If the total length is odd, find the k-th smallest element. +4. Define a helper function `getKth` to find the k-th smallest element in the combined array: + - Base cases: + - If one array is empty, return the k-th element from the other array. + - If k is 1, return the minimum of the first elements of both arrays. + - Recursive case: + - Divide k by 2, compare the k/2-th elements of both arrays, and discard the smaller half. ### Implementation and Code -Here is the implementation of the divide and conquer approach in various languages: - -### JavaScript Implementation: +Here is a live code editor for you to play around with the solution: ```jsx live -var findMedianSortedArrays = function (nums1, nums2) { - const getKth = (nums1, nums2, k) => { - const len1 = nums1.length; - const len2 = nums2.length; - - if (len1 > len2) return getKth(nums2, nums1, k); - if (len1 === 0) return nums2[k - 1]; - if (k === 1) return Math.min(nums1[0], nums2[0]); - - const i = Math.min(len1, Math.floor(k / 2)); - const j = Math.min(len2, Math.floor(k / 2)); +function medianOfTwoSortedArraysProblem() { + const findMedianSortedArrays = (nums1, nums2) => { + const getKth = (nums1, nums2, k) => { + const len1 = nums1.length; + const len2 = nums2.length; + + if (len1 > len2) return getKth(nums2, nums1, k); + if (len1 === 0) return nums2[k - 1]; + if (k === 1) return Math.min(nums1[0], nums2[0]); + + const i = Math.min(len1, Math.floor(k / 2)); + const j = Math.min(len2, Math.floor(k / 2)); + + if (nums1[i - 1] > nums2[j - 1]) { + return getKth(nums1, nums2.slice(j), k - j); + } else { + return getKth(nums1.slice(i), nums2, k - i); + } + }; - if (nums1[i - 1] > nums2[j - 1]) { - return getKth(nums1, nums2.slice(j), k - j); + const len = nums1.length + nums2.length; + if (len % 2 === 1) { + return getKth(nums1, nums2, Math.floor(len / 2) + 1); } else { - return getKth(nums1.slice(i), nums2, k - i); + return ( + (getKth(nums1, nums2, Math.floor(len / 2)) + + getKth(nums1, nums2, Math.floor(len / 2) + 1)) / + 2 + ); } }; - const len = nums1.length + nums2.length; - if (len % 2 === 1) { - return getKth(nums1, nums2, Math.floor(len / 2) + 1); - } else { - return ( - (getKth(nums1, nums2, Math.floor(len / 2)) + - getKth(nums1, nums2, Math.floor(len / 2) + 1)) / - 2 - ); - } -}; -``` - -### Python Implementation: - -```python -class Solution: - def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: - def getKth(nums1, nums2, k): - if len(nums1) > len(nums2): - return getKth(nums2, nums1, k) - if len(nums1) == 0: - return nums2[k - 1] - if k == 1: - return min(nums1[0], nums2[0]) - - i = min(len(nums1), k // 2) - j = min(len(nums2), k // 2) + const nums1 = [1, 3]; + const nums2 = [2]; + const result = findMedianSortedArrays(nums1, nums2); - if nums1[i - 1] > nums2[j - 1]: - return getKth(nums1, nums2[j:], k - j) - else: - return getKth(nums1[i:], nums2, k - i) - - len_combined = len(nums1) + len(nums2) - if len_combined % 2 == 1: - return getKth(nums1, nums2, len_combined // 2 + 1) - else: - return (getKth(nums1, nums2, len_combined // 2) + - getKth(nums1, nums2, len_combined // 2 + 1)) / 2 + return ( +

+

+ Input: nums1 = {"[" + nums1.join(", ") + "]"}, nums2 = {"[" + nums2.join(", ") + "]"} +

+

+ Output: {result} +

+
+ ); +} ``` -### Java Implementation: - -```java -class Solution { - public double findMedianSortedArrays(int[] nums1, int[] nums2) { - int len1 = nums1.length; - int len2 = nums2.length; - - if (len1 > len2) { - return findMedianSortedArrays(nums2, nums1); - } +### Code in Different Languages - int len = len1 + len2; - if (len % 2 == 1) { - return getKth(nums1, nums2, len / 2 + 1); - } else { - return (getKth(nums1, nums2, len / 2) + getKth(nums1, nums2, len / 2 + 1)) / 2.0; - } - } + + + + ```js + var findMedianSortedArrays = function(nums1, nums2) { + const getKth = (nums1, nums2, k) => { + const len1 = nums1.length; + const len2 = nums2.length; - private int getKth(int[] nums1, int[] nums2, int k) { - int len1 = nums1.length; - int len2 = nums2.length; + if (len1 > len2) return getKth(nums2, nums1, k); + if (len1 === 0) return nums2[k - 1]; + if (k === 1) return Math.min(nums1[0], nums2[0]); - if (len1 > len2) { - return getKth(nums2, nums1, k); - } - if (len1 == 0) { - return nums2[k - 1]; - } - if (k == 1) { - return Math.min(nums1[0], nums2[0]); - } + const i = Math.min(len1, Math.floor(k / 2)); + const j = Math.min(len2, Math.floor(k / 2)); - int i = Math.min(len1, k / 2); - int j = Math.min(len2, k / 2); + if (nums1[i - 1] > nums2[j - 1]) { + return getKth(nums1, nums2.slice(j), k - j); + } else { + return getKth(nums1.slice(i), nums2, k - i); + } + }; - if (nums1[i - 1] > nums2[j - 1]) { - return getKth(nums1, Arrays.copyOfRange(nums2, j, len2), k - j); + const len = nums1.length + nums2.length; + if (len % 2 === 1) { + return getKth(nums1, nums2, Math.floor(len / 2) + 1); } else { - return getKth(Arrays.copyOfRange(nums1, i, len1), nums2, k - i); + return (getKth(nums1, nums2, Math.floor(len / 2)) + + getKth(nums1, nums2, Math.floor(len / 2) + 1)) / 2; } - } -} -``` - -### C++ Implementation: - -```c++ -class Solution { -public: - double findMedianSortedArrays(vector& nums1, vector& nums2) { - int len1 = nums1.size(); - int len2 = nums2.size(); + }; + ``` + + + + ```python + class Solution: + def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: + def getKth(nums1, nums2, k): + if len(nums1) > len(nums2): + return getKth(nums2, nums1, k) + if len(nums1) == 0: + return nums2[k - 1] + if k == 1: + return min(nums1[0], nums2[0]) + + i = min(len(nums1), k // 2) + j = min(len(nums2), k // 2) + + if nums1[i - 1] > nums2[j - 1]: + return getKth(nums1, nums2[j:], k - j) + else: + return getKth(nums1[i:], nums2, k - i) - if (len1 > len2) { - return findMedianSortedArrays(nums2, nums1); - } + len_combined = len(nums1) + len(nums2) + if len_combined % 2 == 1: + return getKth(nums1, nums2, len_combined // 2 + 1) + else: + return (getKth(nums1, nums2, len_combined // 2) + + getKth(nums1, nums2, len_combined // 2 + 1)) / 2 + ``` + + + + ```java + class Solution { + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + int len1 = nums1.length; + int len2 = nums2.length; + + if (len1 > len2) { + return findMedianSortedArrays(nums2, nums1); + } - int len = len1 + len2; - if (len % 2 == 1) { - return getKth(nums1, nums2, len / 2 + 1); - } else { - return (getKth(nums1, nums2, len / 2) + getKth(nums1, nums2, len / 2 + 1)) / 2.0; + int len = len1 + len2; + if (len % 2 == 1) { + return getKth(nums1, nums2, len / 2 + 1); + } else { + return (getKth(nums1, nums2, len / 2) + getKth(nums1, nums2, len / 2 + 1)) / 2.0; + } } - } -private: - int getKth(vector& nums1, vector& nums2, int k) { - int len1 = nums1.size(); - int len2 = nums2.size(); + private int getKth(int[] nums1, int[] nums2, int k) { + int len1 = nums1.length; + int len2 = nums2.length; - if (len1 > len2) { - return getKth(nums2, nums1, k); - } - if (len1 == 0) { - return nums2[k - 1]; - } - if (k == 1) { - return min(nums1[0], nums2[0]); - } + if (len1 > len2) { + return getKth(nums2, nums1, k); + } + if (len1 == 0) { + return nums2[k - 1]; + } + if (k == 1) { + return Math.min(nums1[0], nums2[0]); + } - int i = min(len1, k / 2); - int j = min(len2, k / 2); + int i = Math.min(len1, k / 2); + int j = Math.min(len2, k / 2); - if (nums1[i - 1] > nums2[j - 1]) { - return getKth(nums1, vector(nums2.begin() + j, nums2.end()), k - j); - } else { - return getKth(vector(nums1.begin() + i, nums1.end()), nums2, k - i); + if (nums1[i - 1] > nums2[j - 1]) { + return getKth(nums1, Arrays.copyOfRange(nums2, j, len2), k - j); + } else { + return getKth(Arrays.copyOfRange(nums1, i, len1), nums2, k - i); + } } } -}; -``` + ``` + + + + ```cpp + class Solution { + public: + double findMedianSortedArrays(vector& nums1, vector& nums2) { + int len1 = nums1.size(); + int len2 = nums2.size(); + + if (len1 > len2) { + return findMedianSortedArrays(nums2, nums1); + } + + int len = len1 + len2; + if (len % 2 == 1) { + return getKth(nums1, nums2, len / 2 + 1); + } else { + return (getKth(nums1, nums2, len / 2) + getKth(nums1, nums2, len / 2 + 1)) / 2.0; + } + } -### C Implementation: + private: + int getKth(vector& nums1, vector& nums2, int k) { + int len1 = nums1.size(); + int len2 = nums2.size(); + + if (len1 > len2) { + return getKth(nums2, nums1, k); + } + if (len 1 == 0) { + return nums2[k - 1]; + } + if (k == 1) { + return min(nums1[0], nums2[0]); + } - - + int i = min(len1, k / 2); + int j = min(len2, k / 2); -```c + if (nums1[i - 1] > nums2[j - 1]) { + return getKth(nums1, vector(nums2.begin() + j, nums2.end()), k - j); + } else { + return getKth(vector(nums1.begin() + i, nums1.end()), nums2, k - i); + } + } + }; + ``` + + + + ```c double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { if (nums1Size > nums2Size) { return findMedianSortedArrays(nums2, nums2Size, nums1, nums1Size); @@ -681,44 +682,40 @@ private: return getKth(nums1 + i, nums1Size - i, nums2, nums2Size, k - i); } } -``` - - - - - - -```ts -function findMedianSortedArrays(nums1: number[], nums2: number[]): number { - const getKth = (nums1: number[], nums2: number[], k: number): number => { - if (nums1.length > nums2.length) return getKth(nums2, nums1, k); - if (nums1.length === 0) return nums2[k - 1]; - if (k === 1) return Math.min(nums1[0], nums2[0]); - - const i = Math.min(nums1.length, Math.floor(k / 2)); - const j = Math.min(nums2.length, Math.floor(k / 2)); + ``` + + + + ```ts + function findMedianSortedArrays(nums1: number[], nums2: number[]): number { + const getKth = (nums1: number[], nums2: number[], k: number): number => { + if (nums1.length > nums2.length) return getKth(nums2, nums1, k); + if (nums1.length === 0) return nums2[k - 1]; + if (k === 1) return Math.min(nums1[0], nums2[0]); + + const i = Math.min(nums1.length, Math.floor(k / 2)); + const j = Math.min(nums2.length, Math.floor(k / 2)); + + if (nums1[i - 1] > nums2[j - 1]) { + return getKth(nums1, nums2.slice(j), k - j); + } else { + return getKth(nums1.slice(i), nums2, k - i); + } + }; - if (nums1[i - 1] > nums2[j - 1]) { - return getKth(nums1, nums2.slice(j), k - j); - } else { - return getKth(nums1.slice(i), nums2, k - i); + const len = nums1.length + nums2.length; + if (len % 2 === 1) { + return getKth(nums1, nums2, Math.floor(len / 2) + 1); + } else { + return ( + (getKth(nums1, nums2, Math.floor(len / 2)) + + getKth(nums1, nums2, Math.floor(len / 2) + 1)) / + 2 + ); + } } - }; - - const len = nums1.length + nums2.length; - if (len % 2 === 1) { - return getKth(nums1, nums2, Math.floor(len / 2) + 1); - } else { - return ( - (getKth(nums1, nums2, Math.floor(len / 2)) + - getKth(nums1, nums2, Math.floor(len / 2) + 1)) / - 2 - ); - } -} -``` - - + ``` + ### Complexity Analysis @@ -747,38 +744,35 @@ Explanation: merged array = [1, 2, 3, 4] and median is (2 + 3) / 2 = 2.5. + :::info -**Note**: The binary search approach is more efficient than the divide and conquer approach as it has a better time complexity of $O(log(min(n, m)))$ compared to the divide and conquer approach. However, both approaches provide a solution to the problem of finding the median of two sorted arrays. +**Note**: The binary search approach is more efficient than the divide and conquer approach as it has a better time complexity of $O(log(min(n, m)))$ compared to the divide and conquer approach. However, both approaches provide a solution to the problem of finding the median of two sorted arrays. -**Which approach is best for you?** +**Which approach is best for you?** The binary search approach is more efficient and recommended for solving the problem of finding the median of two sorted arrays. However, the divide and conquer approach is also a valid solution and can be used if needed. ::: -:::tip -When asked to find the median of two sorted arrays, a direct approach that merges the two arrays and then finds the median will work but isn't optimal. Given the problem's constraints, we can leverage the fact that the arrays are already sorted and use binary search to find the median in $O(\log(\min(n, m)))$ time complexity. +:::tip +When asked to find the median of two sorted arrays, a direct approach that merges the two arrays and then finds the median will work but isn't optimal. Given the problem's constraints, we can leverage the fact that the arrays are already sorted and use binary search to find the median in $$ O(\log(\min(n, m))) $$ time complexity. The key idea is to use binary search to partition the smaller array in such a way that we can easily find the median by comparing elements around the partition. #### Detailed Explanation -1. **Ensure the Smaller Array is First**: - +1. **Ensure the Smaller Array is First**: - This step is to make sure we always perform the binary search on the smaller array, which helps us manage the partition logic more easily. Let $$ \text{nums1} $$ be the smaller array and $$ \text{nums2} $$ be the larger array. 2. **Set Up Binary Search**: - - Initialize $$ \text{low} $$ and $$ \text{high} $$ pointers for the binary search on $$ \text{nums1} $$. - We aim to partition $$ \text{nums1} $$ and $$ \text{nums2} $$ such that the left side of the combined arrays contains half of the elements, and the right side contains the other half. 3. **Partitioning the Arrays**: - - Calculate $$ \text{partitionX} $$ as the midpoint of $$ \text{nums1} $$. - - Calculate $$ \text{partitionY} $$ such that the left side of the combined arrays has the same number of elements as the right side. This can be achieved by: - + - Calculate $$ \text{partitionY} $$ such that the left side of the combined arrays has the same number of elements as the right side. This can be achieved by: $$ \text{partitionY} = \frac{(x + y + 1)}{2} - \text{partitionX} $$ @@ -786,19 +780,16 @@ The key idea is to use binary search to partition the smaller array in such a wa where $$ x $$ and $$ y $$ are the lengths of $$ \text{nums1} $$ and $$ \text{nums2} $$ respectively. 4. **Boundary Conditions**: - - - Handle cases where partitions might go out of bounds. If $$ \text{partitionX} $$ is 0, it means there are no elements on the left side of $$ \text{nums1} $$. If $$ \text{partitionX} $$ is $x$, it means there are no elements on the right side of $$ \text{nums1} $$. + - Handle cases where partitions might go out of bounds. If $$ \text{partitionX} $$ is 0, it means there are no elements on the left side of $$ \text{nums1} $$. If $$ \text{partitionX} $$ is $$ x $$, it means there are no elements on the right side of $$ \text{nums1} $$. 5. **Check Valid Partition**: - - A valid partition is one where the maximum element on the left side of both partitions is less than or equal to the minimum element on the right side of both partitions: $$ \text{maxX} \leq \text{minY} \quad \text{and} \quad \text{maxY} \leq \text{minX} $$ - Here, $\text{maxX}$ is the largest element on the left side of $\text{nums1}$, $\text{minX}$ is the smallest element on the right side of $\text{nums1}$, and similarly for $\text{nums2}$. + Here, $$ \text{maxX} $$ is the largest element on the left side of $$ \text{nums1} $$, $$ \text{minX} $$ is the smallest element on the right side of $$ \text{nums1} $$, and similarly for $$ \text{nums2} $$. 6. **Calculate the Median**: - - If the total number of elements $$ (x + y) $$ is even, the median is the average of the two middle values: $$ \text{median} = \frac{\text{max(maxX, maxY)} + \text{min(minX, minY)}}{2} @@ -809,11 +800,12 @@ The key idea is to use binary search to partition the smaller array in such a wa $$ 7. **Adjust Binary Search**: - - If $\text{maxX} > \text{minY}$, it means we need to move the partition in $\text{nums1}$ to the left, so adjust $\text{high}$. - - If $\text{maxY} > \text{minX}$, it means we need to move the partition in $\text{nums1}$ to the right, so adjust $\text{low}$. + - If $$ \text{maxX} > \text{minY} $$, it means we need to move the partition in $$ \text{nums1} $$ to the left, so adjust $$ \text{high} $$. + - If $$ \text{maxY} > \text{minX} $$, it means we need to move the partition in $$ \text{nums1} $$ to the right, so adjust $$ \text{low} $$. ::: + ## References - [LeetCode Problem](https://leetcode.com/problems/median-of-two-sorted-arrays/description/) From 3ec8a45cb3c8335d2d3dad8d28607f59ba874ffd Mon Sep 17 00:00:00 2001 From: Nikita Saini Date: Sun, 9 Jun 2024 14:21:14 +0530 Subject: [PATCH 7/7] Create-lc-0017-Letter-Combinations-of-a-Phone-Number Created leetcode solution on problem 0017 using python, java, typescript, javascript, cpp --- ...7-Letter-Combinations-of-a-Phone-Number.md | 316 ++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 dsa-solutions/lc-solutions/0000-0099/0017-Letter-Combinations-of-a-Phone-Number.md diff --git a/dsa-solutions/lc-solutions/0000-0099/0017-Letter-Combinations-of-a-Phone-Number.md b/dsa-solutions/lc-solutions/0000-0099/0017-Letter-Combinations-of-a-Phone-Number.md new file mode 100644 index 000000000..de07f5ca6 --- /dev/null +++ b/dsa-solutions/lc-solutions/0000-0099/0017-Letter-Combinations-of-a-Phone-Number.md @@ -0,0 +1,316 @@ +--- +id: Letter Combinations of a Phone Number +title: Letter Combinations of a Phone Number (LeetCode) +sidebar_label: 0017-Letter-Combinations-of-a-Phone-Number +tags: + - Back Tracking + - Mapping + - String +description: The problem requires generating all letter combinations corresponding to given digits (2-9). The solution utilizes backtracking to explore all combinations efficiently, employing a recursive approach in Java. +--- + +## Problem Description + +| Problem Statement | Solution Link | LeetCode Profile | +| :----------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------- | +| [Letter Combinations of a Phone Number](https://leetcode.com/problems/Letter Combinations of a Phone Number/) | [Letter Combinations of a Phone Number Solution on LeetCode](https://leetcode.com/problems/Letter Combinations of a Phone Number/solutions/5055810/video-two-pointer-solution/) | [gabaniyash846](https://leetcode.com/u/gabaniyash846/) | + +### Problem Description + +## Problem Statement: +Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent. Return the answer in any order. + +### Examples + +#### Example 1 + +- **Input:** `digits = "23"` +- **Output:** `["ad","ae","af","bd","be","bf","cd","ce","cf"]` + +#### Example 2 + +- **Input:** `digits = ""` +- **Output:** `[]` + + +#### Example 3 + +- **Input:** `2` +- **Output:** `["a","b","c"]` + +### Constraints: +- `0 ≤ digits.length ≤ 4` +- `0 ≤ digits.length ≤ 4digits[𝑖]` +- `digits[i] is a digit in the range ['2', '9'].` +- `A mapping of digits to letters (similar to telephone buttons) is given below. Note that 1 does not map to any letters.` + +### Approach + +1. **Mapping Digits to Letters:** + - Define a mapping of digits to their corresponding letters, similar to telephone buttons. + +2. **Backtracking Function:** + - Define a recursive backtracking function to generate all possible combinations. + - The function takes four parameters: + - `index`: The current index in the digits string. + - `path`: The current combination of letters. + - If the index is equal to the length of the digits string, it means we have reached the end of a combination, so we add it to the result list. + - Otherwise, for each letter corresponding to the current digit, we append it to the current combination and recursively call the function with the next index. + - After the recursive call, we remove the last character from the combination (backtracking). + +3. **Base Case:** + - If the length of the current combination is equal to the length of the input digits string, we add the combination to the result list. + +4. **Main Function:** + - Initialize an empty list to store the combinations. + - Call the backtracking function with the initial index set to 0 and an empty string as the initial combination. + - Return the list of combinations. + +This approach ensures that all possible combinations are generated using backtracking, and the result is returned in the desired format. + +### Solution Code + +#### Python + +```python +class Solution: + def letterCombinations(self, digits: str) -> List[str]: + if not digits: + return [] + + digit_to_letters = { + '2': 'abc', + '3': 'def', + '4': 'ghi', + '5': 'jkl', + '6': 'mno', + '7': 'pqrs', + '8': 'tuv', + '9': 'wxyz' + } + + def backtrack(index, path): + if index == len(digits): + combinations.append(path) + return + for letter in digit_to_letters[digits[index]]: + backtrack(index + 1, path + letter) + + combinations = [] + backtrack(0, '') + return combinations +``` + +#### Java + +```java +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Solution { + private Map digitToLetters = new HashMap<>(); + + public Solution() { + digitToLetters.put('2', "abc"); + digitToLetters.put('3', "def"); + digitToLetters.put('4', "ghi"); + digitToLetters.put('5', "jkl"); + digitToLetters.put('6', "mno"); + digitToLetters.put('7', "pqrs"); + digitToLetters.put('8', "tuv"); + digitToLetters.put('9', "wxyz"); + } + + public List letterCombinations(String digits) { + List combinations = new ArrayList<>(); + if (digits == null || digits.isEmpty()) { + return combinations; + } + backtrack(combinations, digits, 0, new StringBuilder()); + return combinations; + } + + private void backtrack(List combinations, String digits, int index, StringBuilder path) { + if (index == digits.length()) { + combinations.add(path.toString()); + return; + } + String letters = digitToLetters.get(digits.charAt(index)); + for (char letter : letters.toCharArray()) { + path.append(letter); + backtrack(combinations, digits, index + 1, path); + path.deleteCharAt(path.length() - 1); + } + } + + public static void main(String[] args) { + Solution solution = new Solution(); + List result = solution.letterCombinations("23"); + System.out.println(result); // Output: [ad, ae, af, bd, be, bf, cd, ce, cf] + } +} +``` + +#### CPP: +```cpp +#include +#include +#include + +using namespace std; + +class Solution { +private: + unordered_map digitToLetters; + vector combinations; + +public: + Solution() { + digitToLetters = { + {'2', "abc"}, + {'3', "def"}, + {'4', "ghi"}, + {'5', "jkl"}, + {'6', "mno"}, + {'7', "pqrs"}, + {'8', "tuv"}, + {'9', "wxyz"} + }; + } + + vector letterCombinations(string digits) { + if (digits.empty()) return {}; + backtrack(digits, 0, ""); + return combinations; + } + + void backtrack(const string& digits, int index, string path) { + if (index == digits.length()) { + combinations.push_back(path); + return; + } + for (char letter : digitToLetters[digits[index]]) { + backtrack(digits, index + 1, path + letter); + } + } +}; + +int main() { + Solution solution; + vector result = solution.letterCombinations("23"); + for (const string& comb : result) { + cout << comb << " "; + } + // Output: ad ae af bd be bf cd ce cf + return 0; +} +``` + +#### JavaScript +```js +/** + * @param {string} digits + * @return {string[]} + */ +var letterCombinations = function(digits) { + if (digits.length === 0) return []; + + const digitToLetters = { + '2': 'abc', + '3': 'def', + '4': 'ghi', + '5': 'jkl', + '6': 'mno', + '7': 'pqrs', + '8': 'tuv', + '9': 'wxyz' + }; + + const combinations = []; + + const backtrack = (index, path) => { + if (index === digits.length) { + combinations.push(path); + return; + } + const letters = digitToLetters[digits.charAt(index)]; + for (let letter of letters) { + backtrack(index + 1, path + letter); + } + }; + + backtrack(0, ''); + return combinations; +}; + +// Example usage: +console.log(letterCombinations("23")); // Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"] +``` + +#### TypeScript +```ts +class Solution { + private digitToLetters: { [key: string]: string } = { + '2': 'abc', + '3': 'def', + '4': 'ghi', + '5': 'jkl', + '6': 'mno', + '7': 'pqrs', + '8': 'tuv', + '9': 'wxyz' + }; + + letterCombinations(digits: string): string[] { + const combinations: string[] = []; + + const backtrack = (index: number, path: string): void => { + if (index === digits.length) { + combinations.push(path); + return; + } + const letters = this.digitToLetters[digits.charAt(index)]; + for (let letter of letters) { + backtrack(index + 1, path + letter); + } + }; + + if (digits.length !== 0) { + backtrack(0, ''); + } + + return combinations; + } +} + +// Example usage: +const solution = new Solution(); +console.log(solution.letterCombinations("23")); // Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"] +``` + +### Step-by-Step Algorithm + +Here's a step-by-step algorithm for generating all possible letter combinations of a given string of digits using backtracking: + +1. **Define a mapping of digits to letters:** + - Create a map where each digit from 2 to 9 is mapped to its corresponding letters on a telephone keypad. + +2. **Define a backtracking function:** + - The function will take the following parameters: + - `index`: The current index in the digits string. + - `path`: The current combination of letters. + - If the index is equal to the length of the digits string, it means we have formed a complete combination, so add it to the result list. + - Otherwise, for each letter corresponding to the current digit at the given index, append it to the current combination and recursively call the function with the next index. + - After the recursive call, remove the last character from the combination (backtracking). + +3. **Base Case:** + - If the length of the current combination is equal to the length of the input digits string, add the combination to the result list. + +4. **Main Function:** + - Initialize an empty list to store the combinations. + - Call the backtracking function with the initial index set to 0 and an empty string as the initial combination. + - Return the list of combinations. + +This algorithm ensures that all possible combinations are generated by exploring all valid paths through backtracking. \ No newline at end of file