|
1 | 1 | //! https://leetcode.com/problems/median-of-two-sorted-arrays/
|
2 | 2 | //! TODO 这题可读性最好最容易记的应该是find_kth递归的解法,我写的Rust解法太长了可读性并不好,建议看我写的Python解法版本
|
3 | 3 |
|
4 |
| -struct Solution; |
5 |
| - |
6 |
| -impl Solution { |
7 |
| - /// [4ms, O(n*logn)]即便用了两个数组合并后排序的完全没利用上两个数组已经有序的笨方法,Rust的性能还是能跑进4ms |
8 |
| - fn my_brute_force(mut nums1: Vec<i32>, mut nums2: Vec<i32>) -> f64 { |
9 |
| - if nums1.len() < nums2.len() { |
10 |
| - return Self::my_brute_force(nums2, nums1); |
11 |
| - } |
12 |
| - nums1.append(&mut nums2); |
13 |
| - nums1.sort_unstable(); |
14 |
| - let len = nums1.len(); |
15 |
| - if len % 2 == 0 { |
16 |
| - (nums1[len / 2 - 1] + nums1[len / 2]) as f64 / 2_f64 |
17 |
| - } else { |
18 |
| - f64::from(nums1[len / 2]) |
19 |
| - } |
| 4 | +/// [4ms, O(n*logn)]即便用了两个数组合并后排序的完全没利用上两个数组已经有序的笨方法,Rust的性能还是能跑进4ms |
| 5 | +fn my_brute_force(mut nums1: Vec<i32>, mut nums2: Vec<i32>) -> f64 { |
| 6 | + if nums1.len() < nums2.len() { |
| 7 | + return my_brute_force(nums2, nums1); |
20 | 8 | }
|
| 9 | + nums1.append(&mut nums2); |
| 10 | + nums1.sort_unstable(); |
| 11 | + let len = nums1.len(); |
| 12 | + if len % 2 == 0 { |
| 13 | + (nums1[len / 2 - 1] + nums1[len / 2]) as f64 / 2_f64 |
| 14 | + } else { |
| 15 | + f64::from(nums1[len / 2]) |
| 16 | + } |
| 17 | +} |
21 | 18 |
|
22 |
| - /// [0ms, O(n)]既然两个数组已经有序,那么可以用归并排序的归并操作去合并数组提升性能,使用二分法能达到更快的logn时间复杂度 |
23 |
| - fn merge_sort_solution(nums1: Vec<i32>, nums2: Vec<i32>) -> f64 { |
24 |
| - let (m, n, mut i, mut j) = (nums1.len(), nums2.len(), 0_usize, 0_usize); |
25 |
| - let len = m + n; |
26 |
| - let half_len = len / 2; |
27 |
| - let mut merged = Vec::with_capacity(len); |
28 |
| - while i < m && j < n { |
29 |
| - if nums1[i] <= nums2[j] { |
30 |
| - merged.push(nums1[i]); |
31 |
| - i += 1; |
32 |
| - } else { |
33 |
| - merged.push(nums2[j]); |
34 |
| - j += 1; |
35 |
| - } |
36 |
| - } |
37 |
| - |
38 |
| - // 如果元素个数已经够了,就提前返回,提升性能 |
39 |
| - if merged.len() > half_len { |
40 |
| - return if len % 2 == 0 { |
41 |
| - (merged[half_len - 1] + merged[half_len]) as f64 / 2_f64 |
42 |
| - } else { |
43 |
| - merged[half_len] as f64 |
44 |
| - }; |
45 |
| - } |
46 |
| - |
47 |
| - while i < m { |
| 19 | +/// [0ms, O(n)]既然两个数组已经有序,那么可以用归并排序的归并操作去合并数组提升性能,使用二分法能达到更快的logn时间复杂度 |
| 20 | +fn merge_sort_solution(nums1: Vec<i32>, nums2: Vec<i32>) -> f64 { |
| 21 | + let (m, n, mut i, mut j) = (nums1.len(), nums2.len(), 0_usize, 0_usize); |
| 22 | + let len = m + n; |
| 23 | + let half_len = len / 2; |
| 24 | + let mut merged = Vec::with_capacity(len); |
| 25 | + while i < m && j < n { |
| 26 | + if nums1[i] <= nums2[j] { |
48 | 27 | merged.push(nums1[i]);
|
49 | 28 | i += 1;
|
50 |
| - } |
51 |
| - while j < n { |
| 29 | + } else { |
52 | 30 | merged.push(nums2[j]);
|
53 | 31 | j += 1;
|
54 | 32 | }
|
55 |
| - if len % 2 == 0 { |
| 33 | + } |
| 34 | + |
| 35 | + // 如果元素个数已经够了,就提前返回,提升性能 |
| 36 | + if merged.len() > half_len { |
| 37 | + return if len % 2 == 0 { |
56 | 38 | (merged[half_len - 1] + merged[half_len]) as f64 / 2_f64
|
57 | 39 | } else {
|
58 | 40 | merged[half_len] as f64
|
59 |
| - } |
| 41 | + }; |
60 | 42 | }
|
61 |
| -} |
62 | 43 |
|
63 |
| -#[cfg(test)] |
64 |
| -mod test_find_median_sorted_arrays { |
65 |
| - use super::Solution; |
66 |
| - |
67 |
| - const TEST_CASES: [(&[i32], &[i32], f64); 17] = [ |
68 |
| - (&[1, 2, 3, 4], &[3, 6, 8, 9], 3.5), |
69 |
| - (&[1, 5, 6, 7], &[2, 3, 4, 8], 4.5), |
70 |
| - (&[1, 2], &[3, 4, 5, 6, 7], 4f64), |
71 |
| - (&[4, 5, 6], &[1, 2, 3], 3.5), |
72 |
| - (&[4, 5], &[1, 2, 3, 6], 3.5), |
73 |
| - (&[1, 3], &[2, 4, 5, 6], 3.5), |
74 |
| - (&[1, 2], &[3, 4, 5, 6], 3.5), |
75 |
| - (&[1, 3], &[2, 4, 5], 3f64), |
76 |
| - (&[1, 2, 3], &[4, 5], 3f64), |
77 |
| - (&[3, 4], &[1, 2, 5], 3f64), |
78 |
| - (&[-2, -1], &[3], -1f64), |
79 |
| - (&[1, 3], &[2], 2_f64), |
80 |
| - (&[3], &[-2, -1], -1f64), |
81 |
| - (&[1, 2], &[3, 4], 2.5), |
82 |
| - (&[4, 5], &[1, 2, 3], 3f64), |
83 |
| - (&[1, 2], &[1, 2, 3], 2_f64), |
84 |
| - (&[1, 2, 3], &[1, 2, 3], 2_f64), |
85 |
| - ]; |
| 44 | + while i < m { |
| 45 | + merged.push(nums1[i]); |
| 46 | + i += 1; |
| 47 | + } |
| 48 | + while j < n { |
| 49 | + merged.push(nums2[j]); |
| 50 | + j += 1; |
| 51 | + } |
| 52 | + if len % 2 == 0 { |
| 53 | + (merged[half_len - 1] + merged[half_len]) as f64 / 2_f64 |
| 54 | + } else { |
| 55 | + merged[half_len] as f64 |
| 56 | + } |
| 57 | +} |
| 58 | +const TEST_CASES: [(&[i32], &[i32], f64); 17] = [ |
| 59 | + (&[1, 2, 3, 4], &[3, 6, 8, 9], 3.5), |
| 60 | + (&[1, 5, 6, 7], &[2, 3, 4, 8], 4.5), |
| 61 | + (&[1, 2], &[3, 4, 5, 6, 7], 4_f64), |
| 62 | + (&[4, 5, 6], &[1, 2, 3], 3.5), |
| 63 | + (&[4, 5], &[1, 2, 3, 6], 3.5), |
| 64 | + (&[1, 3], &[2, 4, 5, 6], 3.5), |
| 65 | + (&[1, 2], &[3, 4, 5, 6], 3.5), |
| 66 | + (&[1, 3], &[2, 4, 5], 3_f64), |
| 67 | + (&[1, 2, 3], &[4, 5], 3_f64), |
| 68 | + (&[3, 4], &[1, 2, 5], 3_f64), |
| 69 | + (&[-2, -1], &[3], -1_f64), |
| 70 | + (&[1, 3], &[2], 2_f64), |
| 71 | + (&[3], &[-2, -1], -1_f64), |
| 72 | + (&[1, 2], &[3, 4], 2.5), |
| 73 | + (&[4, 5], &[1, 2, 3], 3_f64), |
| 74 | + (&[1, 2], &[1, 2, 3], 2_f64), |
| 75 | + (&[1, 2, 3], &[1, 2, 3], 2_f64), |
| 76 | +]; |
86 | 77 |
|
87 |
| - #[test] |
88 |
| - fn test_my_brute_force() { |
89 |
| - for &(nums1, nums2, expected) in TEST_CASES.iter() { |
90 |
| - assert_eq!( |
91 |
| - Solution::my_brute_force(nums1.to_vec(), nums2.to_vec()), |
92 |
| - expected |
93 |
| - ); |
94 |
| - } |
| 78 | +#[test] |
| 79 | +fn test_my_brute_force() { |
| 80 | + for (nums1, nums2, expected) in TEST_CASES { |
| 81 | + assert!((my_brute_force(nums1.to_vec(), nums2.to_vec()) - expected).abs() < f64::EPSILON); |
95 | 82 | }
|
| 83 | +} |
96 | 84 |
|
97 |
| - #[test] |
98 |
| - fn test_merge_sort_solution() { |
99 |
| - for &(nums1, nums2, expected) in TEST_CASES.iter() { |
100 |
| - assert_eq!( |
101 |
| - Solution::merge_sort_solution(nums1.to_vec(), nums2.to_vec()), |
102 |
| - expected |
103 |
| - ); |
104 |
| - } |
| 85 | +#[test] |
| 86 | +fn test_merge_sort_solution() { |
| 87 | + for (nums1, nums2, expected) in TEST_CASES { |
| 88 | + assert!( |
| 89 | + (merge_sort_solution(nums1.to_vec(), nums2.to_vec()) - expected).abs() < f64::EPSILON |
| 90 | + ); |
105 | 91 | }
|
106 | 92 | }
|
107 | 93 |
|
@@ -198,9 +184,10 @@ fn find_median_sorted_arrays(nums1: Vec<i32>, nums2: Vec<i32>) -> f64 {
|
198 | 184 | f64::from(nums1[len_a - 1] + nums2[0]) / 2_f64
|
199 | 185 | } else {
|
200 | 186 | // [1,3]、[2,4,5,6]
|
201 |
| - f64::from(nums2[b_divider_right_index - 2].max(nums1[len_a - 1]) |
202 |
| - + nums2[b_divider_right_index - 1]) |
203 |
| - / 2_f64 |
| 187 | + f64::from( |
| 188 | + nums2[b_divider_right_index - 2].max(nums1[len_a - 1]) |
| 189 | + + nums2[b_divider_right_index - 1], |
| 190 | + ) / 2_f64 |
204 | 191 | }
|
205 | 192 | } else {
|
206 | 193 | // [1,2]、[3,4,5,6,7]
|
|
0 commit comments