123 lines
4.3 KiB
YAML
123 lines
4.3 KiB
YAML
title: Median of Two Sorted Arrays
|
|
slug: median-of-two-sorted-arrays
|
|
difficulty: hard
|
|
leetcode_id: 4
|
|
leetcode_url: https://leetcode.com/problems/median-of-two-sorted-arrays/
|
|
categories:
|
|
- arrays
|
|
- binary-search
|
|
patterns:
|
|
- binary-search
|
|
|
|
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)).
|
|
|
|
constraints: |
|
|
- nums1.length == m
|
|
- nums2.length == n
|
|
- 0 <= m <= 1000
|
|
- 0 <= n <= 1000
|
|
- 1 <= m + n <= 2000
|
|
- -10^6 <= nums1[i], nums2[i] <= 10^6
|
|
|
|
examples:
|
|
- input: "nums1 = [1,3], nums2 = [2]"
|
|
output: "2.0"
|
|
explanation: "Merged array is [1,2,3]. Median is 2."
|
|
- input: "nums1 = [1,2], nums2 = [3,4]"
|
|
output: "2.5"
|
|
explanation: "Merged array is [1,2,3,4]. Median is (2+3)/2 = 2.5."
|
|
|
|
explanation:
|
|
approach: |
|
|
1. Binary search on the smaller array for partition point
|
|
2. Partition both arrays such that left half has (m+n+1)//2 elements
|
|
3. Check if partition is valid: max(left) <= min(right)
|
|
4. If valid, compute median from boundary elements
|
|
5. Adjust binary search bounds based on comparison
|
|
|
|
intuition: |
|
|
The median divides the combined array into two halves of equal size. We don't need to
|
|
actually merge; we just need to find the correct partition.
|
|
|
|
If we choose i elements from nums1 for the left half, we need (m+n+1)//2 - i from nums2.
|
|
Binary search on i (0 to m) to find where nums1[i-1] <= nums2[j] and nums2[j-1] <= nums1[i].
|
|
|
|
This is O(log min(m,n)) since we binary search on the smaller array.
|
|
|
|
common_pitfalls:
|
|
- title: Not handling edge cases at partition
|
|
description: |
|
|
When partition is at array boundary (i=0 or i=m), use -inf or inf for boundary values.
|
|
wrong_approach: "Accessing nums1[i-1] when i=0"
|
|
correct_approach: "Use float('-inf') if i == 0"
|
|
|
|
- title: Binary searching on the longer array
|
|
description: |
|
|
Always binary search on the shorter array to ensure valid partition exists
|
|
and for better efficiency.
|
|
|
|
- title: Odd vs even total length
|
|
description: |
|
|
For odd total, median is max of left half.
|
|
For even, it's average of max(left) and min(right).
|
|
|
|
key_takeaways:
|
|
- Binary search on partition, not on values
|
|
- Partition both arrays to have equal halves
|
|
- Handle boundary conditions with infinity
|
|
- O(log min(m,n)) is achievable
|
|
|
|
time_complexity: "O(log min(m,n))"
|
|
space_complexity: "O(1)"
|
|
complexity_explanation: |
|
|
Time: Binary search on the smaller array.
|
|
Space: Only constant extra variables.
|
|
|
|
solutions:
|
|
- approach_name: Binary Search on Partition (Optimal)
|
|
is_optimal: true
|
|
code: |
|
|
def find_median_sorted_arrays(nums1: list[int], nums2: list[int]) -> float:
|
|
# Ensure nums1 is the smaller array
|
|
if len(nums1) > len(nums2):
|
|
nums1, nums2 = nums2, nums1
|
|
|
|
m, n = len(nums1), len(nums2)
|
|
left, right = 0, m
|
|
half_len = (m + n + 1) // 2
|
|
|
|
while left <= right:
|
|
i = (left + right) // 2 # Partition in nums1
|
|
j = half_len - i # Partition in nums2
|
|
|
|
# Handle edge cases with infinity
|
|
nums1_left = float('-inf') if i == 0 else nums1[i - 1]
|
|
nums1_right = float('inf') if i == m else nums1[i]
|
|
nums2_left = float('-inf') if j == 0 else nums2[j - 1]
|
|
nums2_right = float('inf') if j == n else nums2[j]
|
|
|
|
if nums1_left <= nums2_right and nums2_left <= nums1_right:
|
|
# Found valid partition
|
|
if (m + n) % 2 == 1:
|
|
return max(nums1_left, nums2_left)
|
|
else:
|
|
return (max(nums1_left, nums2_left) +
|
|
min(nums1_right, nums2_right)) / 2
|
|
|
|
elif nums1_left > nums2_right:
|
|
# Too many elements from nums1 in left half
|
|
right = i - 1
|
|
else:
|
|
# Too few elements from nums1 in left half
|
|
left = i + 1
|
|
|
|
return 0.0 # Should never reach here
|
|
explanation: |
|
|
Binary search to find correct partition point in the smaller array.
|
|
Partition is valid when all left elements <= all right elements.
|
|
Compute median from the four boundary elements.
|