Skip to content

Commit

Permalink
feat/Find Median of Two Sorted Arrays Without Merging
Browse files Browse the repository at this point in the history
  • Loading branch information
Rudrajiii committed Oct 28, 2024
1 parent 78ce39a commit 65cdc7a
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
78 changes: 78 additions & 0 deletions Data-Structures/Array/findMedianSortedArraysWithoutMerging.js
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;
}
}
}
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);
});
});

0 comments on commit 65cdc7a

Please sign in to comment.