1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
//! Median of Two Sorted Arrays [leetcode: median_of_two_sorted_arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/) //! //! There are two sorted arrays **nums1** and **nums2** of size m and n respectively. //! //! Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). //! //! You may assume **nums1** and **nums2** cannot be both empty. //! //! **Example1:** //! //! ``` //! nums1 = [1, 3] //! nums2 = [2] //! //! The median is 2.0 //! ``` //! //! **Example2:** //! //! ``` //! nums1 = [1, 2] //! nums2 = [3, 4] //! //! The median is (2 + 3)/2 = 2.5 //! ``` //! /// # Solutions /// /// # Approach 1: Recursive Approach /// /// * Time complexity: O(log(min(m,n))) /// /// * Space complexity: O(1) /// /// * Runtime: 0 ms /// * Memory: 2.5 MB /// /// ```rust /// // 思路 /// // 将 nums1 与 nums2 使用二分法分别将其拆分为两半, nums1_left, nums1_right, nums2_left, nums2_right; /// // 将 nums1_left 与 nums2_left 合并 part_left;nums1_right 与 nums2_right 合并 part_right /// // 当 part_left == part_right 且 max(part_left)≤min(part_right) 时,中间数即为 (max(left_part)+min(right_part)) / 2 /// pub fn find_median_sorted_arrays(nums1: Vec<i32>, nums2: Vec<i32>) -> f64 { /// let mut first = &nums1; /// let mut second = &nums2; /// /// if first.len() > second.len() { /// first = &nums2; /// second = &nums1 /// } /// /// let m = first.len(); /// let n = second.len(); /// let mut low = 0; /// let mut high = m; /// let half_len = ((n - m + 1) >> 1) + m; /// /// while low <= high { /// let mid_first = ((high - low) >> 1) + low; /// let mid_second = half_len - mid_first; /// /// let first_left = if mid_first == 0 { std::i32::MIN } else { first[mid_first - 1] }; /// let first_right = if mid_first == m { std::i32::MAX } else { first[mid_first] }; /// let second_left = if mid_second == 0 { std::i32::MIN } else { second[mid_second - 1] }; /// let second_right = if mid_second == n { std::i32::MAX } else { second[mid_second] }; /// /// if first_left <= second_right && second_left <= first_right { /// if (n + m) & 1 == 0 { /// // 避免溢出,不使用 (right_min + left_max) as f64 / 2.0 的方式 /// let mut left_max = first_left.max(second_left); /// let mut right_min = first_right.min(second_right); /// if left_max > right_min { /// let tmp = left_max; /// left_max = right_min; /// right_min = tmp; /// } /// return (right_min - left_max) as f64 / 2.0 + (left_max as f64); /// } else { /// return first_left.max(second_left) as f64 /// } /// } else if first_left > second_right { /// high = mid_first - 1; /// } else { /// low = mid_first + 1; /// } /// } /// 0.0 /// } /// ``` /// pub fn find_median_sorted_arrays(nums1: Vec<i32>, nums2: Vec<i32>) -> f64 { let mut first = &nums1; let mut second = &nums2; if first.len() > second.len() { first = &nums2; second = &nums1 } let m = first.len(); let n = second.len(); let mut low = 0; let mut high = m; let half_len = ((n - m + 1) >> 1) + m; while low <= high { let mid_first = ((high - low) >> 1) + low; let mid_second = half_len - mid_first; let first_left = if mid_first == 0 { std::i32::MIN } else { first[mid_first - 1] }; let first_right = if mid_first == m { std::i32::MAX } else { first[mid_first] }; let second_left = if mid_second == 0 { std::i32::MIN } else { second[mid_second - 1] }; let second_right = if mid_second == n { std::i32::MAX } else { second[mid_second] }; if first_left <= second_right && second_left <= first_right { if (n + m) & 1 == 0 { // 避免溢出,不使用 (right_min + left_max) as f64 / 2.0 的方式 let mut left_max = first_left.max(second_left); let mut right_min = first_right.min(second_right); if left_max > right_min { let tmp = left_max; left_max = right_min; right_min = tmp; } return (right_min - left_max) as f64 / 2.0 + (left_max as f64); } else { return first_left.max(second_left) as f64 } } else if first_left > second_right { high = mid_first - 1; } else { low = mid_first + 1; } } 0.0 }