0004-median-of-two-sorted-arrays.rs (3593B)
1/// Given two sorted arrays nums1 and nums2 of size m and n respectively, 2/// return the median of the two sorted arrays. 3/// 4/// The overall run time complexity should be O(log (m+n)). 5/// 6/// 7/// 8/// Example 1: 9/// 10/// Input: nums1 = [1,3], nums2 = [2] 11/// Output: 2.00000 12/// Explanation: merged array = [1,2,3] and median is 2. 13/// 14/// Example 2: 15/// 16/// Input: nums1 = [1,2], nums2 = [3,4] 17/// Output: 2.50000 18/// Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5. 19/// 20/// 21/// 22/// Constraints: 23/// 24/// nums1.length == m 25/// nums2.length == n 26/// 0 <= m <= 1000 27/// 0 <= n <= 1000 28/// 1 <= m + n <= 2000 29/// -106 <= nums1[i], nums2[i] <= 106 30/// 31use leetcode::arg_into; 32 33struct Solution {} 34 35impl Solution { 36 // Arrays a and b can be partitioned into elements which are less 37 // than or equal to the merged array's median (*_l) and those which 38 // are greater or equal (*_g). A constraint that that can be derived 39 // from this is that all elements in the *_l partitions must be smaller 40 // than or equal those in the *_g partitions: 41 // 42 // - a[a_l-1] <= b[b_l] 43 // - b[b_l-1] <= a[a_l] 44 // 45 // Additionally, since the median by definition is the (average) value 46 // of an array's center element(s), the partition lengths must 47 // satisfy the constraint: 48 // 49 // - len(b_l) = (len(a) + len(b) + 1) / 2 - len(a_l) 50 // 51 // Using these contraints, we can binary search for the partition 52 // length a_l to determine all partitions and ultimately the median 53 // of the merged array. 54 55 pub fn find_median_sorted_arrays(nums1: Vec<i32>, nums2: Vec<i32>) -> f64 { 56 if nums1.is_empty() && nums2.is_empty() { 57 return 0f64; 58 } 59 60 let (a, b) = if nums1.len() > nums2.len() { 61 (nums1, nums2) 62 } else { 63 (nums2, nums1) 64 }; 65 66 let mut min = 0; 67 let mut max = a.len(); 68 let n_l = (a.len() + b.len() + 1) / 2; 69 while min != max { 70 let a_l = (max + min) / 2; 71 if a_l > n_l || a_l > 0 && n_l - a_l < b.len() && a[a_l - 1] > b[n_l - a_l] { 72 max = a_l - 1; 73 } else if n_l - a_l > b.len() 74 || n_l - a_l > 0 && a_l < a.len() && b[n_l - a_l - 1] > a[a_l] 75 { 76 min = a_l + 1; 77 } else { 78 min = a_l; 79 max = a_l; 80 } 81 } 82 83 let a_l = min as i32; 84 let b_l = n_l as i32 - a_l; 85 let v = |x: &Vec<i32>, i| { 86 if i >= 0 { 87 x.get(i as usize).cloned() 88 } else { 89 None 90 } 91 }; 92 let m1 = [v(&a, a_l - 1), v(&b, b_l - 1)] 93 .iter() 94 .filter_map(|&p| p) 95 .max() 96 .unwrap(); 97 if (a.len() + b.len()) % 2 == 1 { 98 m1 as f64 99 } else { 100 let m2 = [v(&a, a_l), v(&b, b_l)] 101 .iter() 102 .filter_map(|&p| p) 103 .min() 104 .unwrap(); 105 (m1 as f64 + m2 as f64) / 2.0 106 } 107 } 108} 109 110pub fn main() { 111 println!( 112 "{:?}", 113 Solution::find_median_sorted_arrays(arg_into(1), arg_into(2)) 114 ); 115} 116 117#[cfg(test)] 118mod tests { 119 use crate::Solution; 120 use leetcode::vi; 121 122 #[test] 123 fn test() { 124 assert_eq!( 125 Solution::find_median_sorted_arrays(vi("[1,3]"), vi("[2]")), 126 2.0 127 ); 128 assert_eq!( 129 Solution::find_median_sorted_arrays(vi("[1,2]"), vi("[3,4]")), 130 2.5 131 ); 132 } 133}