|
1 | 1 | /**
|
2 | 2 | * @param {number[]} nums1
|
3 | 3 | * @param {number[]} nums2
|
| 4 | + * Time O(log(N * M)) | Space O(N) |
4 | 5 | * @return {number}
|
5 | 6 | */
|
6 |
| -var findMedianSortedArrays = function (nums1, nums2) { |
7 |
| - let [A, B] = [nums1, nums2]; |
8 |
| - const total = nums1.length + nums2.length; |
9 |
| - const half = Math.floor(total / 2); |
| 7 | + var findMedianSortedArrays = function(nums1, nums2) { |
| 8 | + const canSwap = nums2.length < nums1.length; |
| 9 | + if (canSwap) [nums1, nums2] = [nums2, nums1]; |
10 | 10 |
|
11 |
| - if (B.length < A.length) { |
12 |
| - [A, B] = [B, A]; |
13 |
| - } |
| 11 | + let [ left, right ] = [ 0, nums1.length - 1 ]; |
| 12 | + const totalLength = nums1.length + nums2.length |
| 13 | + const mid = totalLength >> 1; |
| 14 | + const isEven = (totalLength % 2) === 0; |
14 | 15 |
|
15 |
| - let [l, r] = [0, A.length - 1]; |
16 | 16 | while (true) {
|
17 |
| - const i = l + r; |
18 |
| - const j = half - i - 2; |
19 |
| - |
20 |
| - const Aleft = i >= 0 ? A[i] : -Infinity; |
21 |
| - const Aright = i + 1 < A.length ? A[i + 1] : Infinity; |
22 |
| - const Bleft = j >= 0 ? B[j] : -Infinity; |
23 |
| - const Bright = j + 1 < B.length ? B[j + 1] : Infinity; |
24 |
| - |
25 |
| - if (Aleft <= Bright && Bleft <= Aright) { |
26 |
| - if (total % 2) { |
27 |
| - return Math.min(Aright, Bright); |
28 |
| - } |
29 |
| - |
30 |
| - return (Math.max(Aleft, Bleft) + Math.min(Aright, Bright)) / 2; |
31 |
| - } else if (Aleft > Bright) r = i - 1; |
32 |
| - else l = i + 1; |
| 17 | + const mid1 = left + right; |
| 18 | + const mid2 = (mid - mid1) - 2; |
| 19 | + const { aLeft, aRight, bLeft, bRight } = getPointers(nums1, mid1, nums2, mid2); |
| 20 | + |
| 21 | + const isTarget = (aLeft <= bRight) && (bLeft <= aRight); |
| 22 | + if (isTarget) return isEven |
| 23 | + ? (Math.max(aLeft, bLeft) + Math.min(aRight, bRight)) / 2 |
| 24 | + : Math.min(aRight, bRight); |
| 25 | + |
| 26 | + const isTargetGreater = aLeft <= bRight; |
| 27 | + if (isTargetGreater) left = mid1 + 1; |
| 28 | + |
| 29 | + const isTargetLess = bRight < aLeft; |
| 30 | + if (isTargetLess) right = mid1 - 1; |
33 | 31 | }
|
34 |
| -}; |
| 32 | +} |
| 33 | + |
| 34 | +const getPointers = (nums1, mid1, nums2, mid2) => { |
| 35 | + const getLeft = (nums, index) => 0 <= index |
| 36 | + ? nums[index] |
| 37 | + : -Infinity; |
| 38 | + |
| 39 | + const [ aLeft, bLeft ] = [ getLeft(nums1, mid1), getLeft(nums2, mid2) ]; |
| 40 | + |
| 41 | + const getRight = (nums, index) => (index + 1) < nums.length |
| 42 | + ? nums[index + 1] |
| 43 | + : Infinity; |
| 44 | + |
| 45 | + const [ aRight, bRight ] = [ getRight(nums1, mid1), getRight(nums2, mid2) ]; |
| 46 | + |
| 47 | + return { aLeft, aRight, bLeft, bRight }; |
| 48 | +} |
0 commit comments