Skip to content

Commit fd492e1

Browse files
authored
Merge pull request #1 from balaraj74/feature/median-two-sorted-arrays
Add Median of Two Sorted Arrays Algorithm to Divide and Conquer Section
2 parents e2a78d4 + 5f5a2a0 commit fd492e1

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
"""
2+
Median of Two Sorted Arrays
3+
4+
Problem: Given two sorted arrays nums1 and nums2 of sizes m and n,
5+
return the median of the two sorted arrays.
6+
7+
This implementation uses a partition-based divide-and-conquer approach
8+
to achieve optimal time complexity.
9+
10+
Time Complexity: O(log(min(m, n)))
11+
Space Complexity: O(1)
12+
13+
Reference: https://leetcode.com/problems/median-of-two-sorted-arrays/
14+
"""
15+
16+
from __future__ import annotations
17+
18+
19+
def find_median_sorted_arrays(
20+
nums1: list[int | float], nums2: list[int | float]
21+
) -> float:
22+
"""
23+
Find the median of two sorted arrays using binary search.
24+
25+
The algorithm works by partitioning both arrays such that:
26+
- All elements on the left side are smaller than elements on the right side
27+
- The left side has the same number of elements as the right side (or one more)
28+
29+
Args:
30+
nums1: First sorted array
31+
nums2: Second sorted array
32+
33+
Returns:
34+
The median of the two sorted arrays as a float
35+
36+
Raises:
37+
ValueError: If both input arrays are empty
38+
39+
Examples:
40+
>>> find_median_sorted_arrays([1, 3], [2])
41+
2.0
42+
>>> find_median_sorted_arrays([1, 2], [3, 4])
43+
2.5
44+
>>> find_median_sorted_arrays([], [1])
45+
1.0
46+
>>> find_median_sorted_arrays([2], [])
47+
2.0
48+
>>> find_median_sorted_arrays([1, 2, 3, 4, 5], [6, 7, 8])
49+
4.5
50+
>>> find_median_sorted_arrays([1.5, 2.5], [2.0, 3.0])
51+
2.25
52+
>>> find_median_sorted_arrays([1, 1, 1], [1, 1, 1])
53+
1.0
54+
>>> find_median_sorted_arrays([-5, -3, -1], [0, 2, 4])
55+
-0.5
56+
>>> find_median_sorted_arrays([1], [2, 3, 4, 5, 6])
57+
3.5
58+
>>> find_median_sorted_arrays([], [])
59+
Traceback (most recent call last):
60+
...
61+
ValueError: Both input arrays are empty
62+
"""
63+
if not nums1 and not nums2:
64+
raise ValueError("Both input arrays are empty")
65+
66+
# Ensure nums1 is the smaller array for efficiency
67+
if len(nums1) > len(nums2):
68+
nums1, nums2 = nums2, nums1
69+
70+
m, n = len(nums1), len(nums2)
71+
total_left = (m + n + 1) // 2 # Number of elements on the left side
72+
73+
left, right = 0, m
74+
75+
while left <= right:
76+
# Partition indices for nums1 and nums2
77+
i = (left + right) // 2 # Partition index for nums1
78+
j = total_left - i # Partition index for nums2
79+
80+
# Get the boundary elements around the partitions
81+
nums1_left_max = nums1[i - 1] if i > 0 else float("-inf")
82+
nums1_right_min = nums1[i] if i < m else float("inf")
83+
84+
nums2_left_max = nums2[j - 1] if j > 0 else float("-inf")
85+
nums2_right_min = nums2[j] if j < n else float("inf")
86+
87+
# Check if we found the correct partition
88+
if nums1_left_max <= nums2_right_min and nums2_left_max <= nums1_right_min:
89+
# Correct partition found
90+
if (m + n) % 2 == 1:
91+
# Odd total length: median is the max of left side
92+
return float(max(nums1_left_max, nums2_left_max))
93+
else:
94+
# Even total length: median is average of max(left) and min(right)
95+
left_max = max(nums1_left_max, nums2_left_max)
96+
right_min = min(nums1_right_min, nums2_right_min)
97+
return (left_max + right_min) / 2.0
98+
elif nums1_left_max > nums2_right_min:
99+
# We are too far right in nums1, move left
100+
right = i - 1
101+
else:
102+
# We are too far left in nums1, move right
103+
left = i + 1
104+
105+
# This should not be reached if inputs are valid sorted arrays
106+
raise ValueError("Input arrays are not sorted or some unexpected error occurred")
107+
108+
109+
if __name__ == "__main__":
110+
import doctest
111+
112+
doctest.testmod()

0 commit comments

Comments
 (0)