2023-08-03
https://leetcode.com/problems/median-of-two-sorted-arrays/
Given two sorted arrays nums1
and nums2
of size s1
and s2
respectively, return the median of the two sorted arrays.
The overall run time complexity should be O(log (n))
.
where n = s1 + s2.
Example 1:
Input: nums1 = [1,3], nums2 = [2]
Output: 2.00000
Explanation: merged array = [1,2,3] and median is 2.
Example 2:
Input: nums1 = [1,2], nums2 = [3,4]
Output: 2.50000
Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5.
const findMedianSortedArrays = function (nums1, nums2) {
let arr = [...nums1, ...nums2];
arr = arr.sort((a, b) => a - b);
const length = arr.length;
if (length % 2 === 0) {
const mid = length / 2;
return (arr[mid - 1] + arr[mid]) / 2;
} else {
const mid = Math.floor(length / 2);
return arr[mid];
}
};
Spread Operator(…): time complexity is $O(n)$.
And, yes. There is much chance to improve solution.
The algorithm checks the middle element to determine if it’s greater than, less than, or equal to the value being searched for.
This process is repeated on the correct half of the array, essentially reducing the search space by half each time. This is why it’s called a “binary” search. It’s an efficient way to search for a value in a sorted array, with a time complexity of $O(log(n))$.
const findMedianSortedArrays = function (nums1, nums2) {
if (nums1.length > nums2.length) {
[nums1, nums2] = [nums2, nums1];
}
let x = nums1.length;
let y = nums2.length;
let start = 0;
let end = x;
while (start <= end) {
let partitionX = (start + end) >> 1;
let partitionY = ((x + y + 1) >> 1) - partitionX;
let maxLeftX = partitionX === 0 ? -Infinity : nums1[partitionX - 1];
let minRightX = partitionX === x ? Infinity : nums1[partitionX];
let maxLeftY = partitionY === 0 ? -Infinity : nums2[partitionY - 1];
let minRightY = partitionY === y ? Infinity : nums2[partitionY];
if (maxLeftX <= minRightY && maxLeftY <= minRightX) {
if ((x + y) & 1) {
return Math.max(maxLeftX, maxLeftY);
} else {
return (
(Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY)) / 2
);
}
} else if (maxLeftX > minRightY) {
end = partitionX - 1;
} else {
start = partitionX + 1;
}
}
};
while (start <= end) {
let partitionX = (start + end) >> 1;
let partitionY = ((x + y + 1) >> 1) - partitionX;
The binary search is performed in a while
loop. The algorithm calculates partitionX
and partitionY
to divide nums1
and nums2
into left and right halves, respectively. The sum of the elements on the left side should be equal to or one more than the sum on the right side.
let maxLeftX = partitionX === 0 ? -Infinity : nums1[partitionX - 1];
let minRightX = partitionX === x ? Infinity : nums1[partitionX];
let maxLeftY = partitionY === 0 ? -Infinity : nums2[partitionY - 1];
let minRightY = partitionY === y ? Infinity : nums2[partitionY];
The maxLeftX
, minRightX
, maxLeftY
, and minRightY
variables represent the border elements of the partitions in nums1
and nums2
. If a partition has no elements on the left or right side, it uses -Infinity
or Infinity
, respectively, to allow comparisons to be performed correctly.
if (maxLeftX <= minRightY && maxLeftY <= minRightX) {
Here, the algorithm checks whether the current partition is correct. It’s correct if the largest element on the left side of the partition in nums1
(maxLeftX
) is not greater than the smallest element on the right side of the partition in nums2
(minRightY
), and the largest element on the left side of the partition in nums2
(maxLeftY
) is not greater than the smallest element on the right side of the partition in nums1
(minRightX
).
If this condition is met, it means all the elements on the left side of the partition are less than or equal to the elements on the right side, which is the property of a sorted array that the algorithm leverages to find the median.
if ((x + y) & 1) {
return Math.max(maxLeftX, maxLeftY);
} else {
return (Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY)) / 2;
}
Once the correct partition is found, the median is calculated and returned. If the total number of elements in nums1
and nums2
(x + y
) is odd, the median is the maximum element on the left side of the partition. If the total number of elements is even, the median is the average of the maximum element on the left side and the minimum element on the right side.
} else if (maxLeftX > minRightY) {
end = partitionX - 1;
} else {
start = partitionX + 1;
}
Binary search can only be used when the array or list is sorted. If the data is not sorted, you would need to sort it first before using binary search, which can be expensive for large data sets.