-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat/Find Median of Two Sorted Arrays Without Merging
- Loading branch information
Showing
2 changed files
with
116 additions
and
0 deletions.
There are no files selected for viewing
78 changes: 78 additions & 0 deletions
78
Data-Structures/Array/findMedianSortedArraysWithoutMerging.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/** | ||
* Function to find the median of two sorted arrays without merging them. | ||
* This algorithm efficiently uses binary search on the smaller array to achieve O(log(min(n, m))) complexity. | ||
* Sample Problem : https://leetcode.com/problems/median-of-two-sorted-arrays/description/ | ||
* | ||
* Approach: | ||
* 1. Ensure nums1 is the smaller array to reduce the number of binary search operations. | ||
* 2. Use binary search to partition both arrays so that elements on the left are less than or equal to elements on the right. | ||
* 3. Based on the combined array length, find the median directly by averaging or picking the middle element. | ||
* | ||
* Time Complexity: O(log(min(n, m))) - where n and m are the lengths of the two arrays. | ||
* Space Complexity: O(1) - only a constant amount of space is used. | ||
* | ||
* Examples: | ||
* nums1 = [1, 3], nums2 = [2] | ||
* The combined array would be [1, 2, 3] and the median is 2. | ||
* | ||
* nums1 = [1, 2], nums2 = [3, 4] | ||
* The combined array would be [1, 2, 3, 4] and the median is (2 + 3) / 2 = 2.5. | ||
* | ||
* @param {number[]} nums1 - First sorted array. | ||
* @param {number[]} nums2 - Second sorted array. | ||
* @returns {number} - The median of the two sorted arrays. | ||
* @throws Will throw an error if the input arrays are not sorted or valid for median calculation. | ||
*/ | ||
export function findMedianSortedArraysWithoutMerging(nums1, nums2) { | ||
// Checks if array are sorted or not | ||
const isSorted = (arr) => { | ||
for (let i = 1; i < arr.length; i++) { | ||
if (arr[i] < arr[i - 1]) return false; | ||
} | ||
return true; | ||
}; | ||
|
||
if (!isSorted(nums1) || !isSorted(nums2)) { | ||
throw new Error("Input arrays are not sorted or valid for median calculation."); | ||
} | ||
|
||
//First ensure nums1 is the smaller array | ||
if (nums1.length > nums2.length) { | ||
[nums1, nums2] = [nums2, nums1]; | ||
} | ||
|
||
const x = nums1.length; | ||
const y = nums2.length; | ||
let low = 0, high = x; | ||
|
||
while (low <= high) { | ||
const partitionX = Math.floor((low + high) / 2); | ||
const partitionY = Math.floor((x + y + 1) / 2) - partitionX; | ||
|
||
// Edge values in case of partitions at boundaries | ||
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]; | ||
|
||
// Check if partition is correct | ||
if (maxX <= minY && maxY <= minX) { | ||
// Correct partition found, calculate median | ||
const leftMax = Math.max(maxX, maxY); | ||
const rightMin = Math.min(minX, minY); | ||
|
||
if ((x + y) % 2 === 0) { | ||
return (leftMax + rightMin) / 2; | ||
} else { | ||
return leftMax; | ||
} | ||
} else if (maxX > minY) { | ||
// Move towards left in nums1 | ||
high = partitionX - 1; | ||
} else { | ||
// Move towards right in nums1 | ||
low = partitionX + 1; | ||
} | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
Data-Structures/Array/test/findMedianSortedArraysWithoutMerging.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { findMedianSortedArraysWithoutMerging } from '../findMedianSortedArraysWithoutMerging'; | ||
|
||
describe('findMedianSortedArrays', () => { | ||
it('should find the median of two sorted arrays of equal length', () => { | ||
expect(findMedianSortedArraysWithoutMerging([1, 3], [2, 4])).toBe(2.5); | ||
expect(findMedianSortedArraysWithoutMerging([1, 2], [3, 4])).toBe(2.5); | ||
}); | ||
|
||
it('should find the median when arrays have different lengths', () => { | ||
expect(findMedianSortedArraysWithoutMerging([1, 3], [2])).toBe(2); | ||
expect(findMedianSortedArraysWithoutMerging([1, 2, 3], [4, 5])).toBe(3); | ||
}); | ||
|
||
it('should find the median when one array is empty', () => { | ||
expect(findMedianSortedArraysWithoutMerging([], [1])).toBe(1); | ||
expect(findMedianSortedArraysWithoutMerging([], [1, 2, 3])).toBe(2); | ||
}); | ||
|
||
it('should handle single element arrays', () => { | ||
expect(findMedianSortedArraysWithoutMerging([1], [2])).toBe(1.5); | ||
expect(findMedianSortedArraysWithoutMerging([1], [2, 3, 4])).toBe(2.5); | ||
}); | ||
|
||
it('should handle arrays with duplicate elements', () => { | ||
expect(findMedianSortedArraysWithoutMerging([1, 2, 2], [2, 3, 4])).toBe(2); | ||
expect(findMedianSortedArraysWithoutMerging([1, 1, 1], [1, 1, 1])).toBe(1); | ||
}); | ||
|
||
it('should throw an error if the arrays are not sorted', () => { | ||
expect(() => findMedianSortedArraysWithoutMerging([3, 1], [2, 4])).toThrow('Input arrays are not sorted or valid for median calculation.'); | ||
expect(() => findMedianSortedArraysWithoutMerging([1, 3, 5], [4, 2])).toThrow('Input arrays are not sorted or valid for median calculation.'); | ||
}); | ||
|
||
it('should work for larger arrays', () => { | ||
expect(findMedianSortedArraysWithoutMerging([1, 2, 3, 6, 8], [4, 5, 7, 9])).toBe(5); | ||
expect(findMedianSortedArraysWithoutMerging([1, 5, 8, 10], [3, 7, 9, 11, 12])).toBe(8); | ||
}); | ||
}); |