寻找两个有序数组的中位数 问题描述
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
归并法 思路分析
将两个有序数组归并排序为一个数组C,求出数组C的中位数
代码实现 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 class Solution {public : double findMedianSortedArrays (vector <int >& nums1, vector <int >& nums2) { int m = nums1.size(); int n = nums2.size(); vector <int > nums (m + n) ; int i = 0 , j = 0 ; for (int k = 0 ; k < m+n; k++) { if (i == m) { nums[k] = nums2[j]; j++; } else if (j == n) { nums[k] = nums1[i]; i++; } else if (nums1[i] <= nums2[j]) { nums[k] = nums1[i]; i++; } else { nums[k] = nums2[j]; j++; } } if ((m+n) % 2 == 1 ) { return nums[(m + n) / 2 ]; } else { return (nums[(m + n) / 2 - 1 ] + nums[(m + n) / 2 ]) * 0.5f ; } } };
双指针 思路分析
i=0,j=0起始 0<=i<=m,0<=j<=n
A[i]<B[j] i++
A[i]>B[j] j++
i + j = (m+n+1)/2 停止
代码实现 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 class Solution {public : double findMedianSortedArrays (vector <int >& nums1, vector <int >& nums2) { int i = 0 , j = 0 ; int m = nums1.size(); int n = nums2.size(); while (i + j < (m + n + 1 ) / 2 ) { if (i == m) { j++; } else if (j == n) { i++; } else if (nums1[i] <= nums2[j]) { i++; } else { j++; } } int max_left = 0 ; if (i == 0 ) { max_left = nums2[j - 1 ]; } else if (j == 0 ) { max_left = nums1[i - 1 ]; } else { max_left = nums1[i - 1 ] > nums2[j - 1 ] ? nums1[i - 1 ] : nums2[j - 1 ]; } if ((m+n) % 2 == 1 ) { return max_left; } int min_right = 0 ; if (i == m) { min_right = nums2[j]; } else if (j == n) { min_right = nums1[i]; } else { min_right = nums1[i] < nums2[j] ? nums1[i] : nums2[j]; } return (max_left+min_right) * 0.5f ; } };
二分法 思路分析
1.假设中位数的位置在 A B 数组的 i,j位置 0<=i<=m,0<=j<=n 则满足:
1.i+j = (m+n+1)/2
2.集合A(0,i-1)和集合B(0,j-1) 小于 集合A(i,m-1)和集合B(j,n-1)
2.临界处理
1.数组为空
2.i==0 j==0 i==m j==n
代码实现 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 class Solution {public : int Bisection (vector <int >& nums1, vector <int >& nums2, int i, int j) { int index1 = (i + j) / 2 ; int index2 = (nums1.size() + nums2.size() + 1 ) / 2 - index1; if (index1 < nums1.size() && index2 <= nums2.size() && nums1[index1] < nums2[index2 - 1 ]) { return Bisection(nums1, nums2, index1 + 1 , j); } else if (index1 > 0 && index2 <nums2.size() && nums1[index1 - 1 ] > nums2[index2]) { return Bisection(nums1, nums2, i, index1 - 1 ); } return index1; } double findMedianSortedArrays2 (vector <int >& nums1, vector <int >& nums2) { int i = 0 , j = nums1.size(); i = (nums1.size() - nums2.size() + 1 ) / 2 ; i = i >= 0 ? i : 0 ; j = (nums1.size() + nums2.size() + 1 ) / 2 ; j = j <= nums1.size() ? j : nums1.size(); int index1 = Bisection(nums1,nums2,i,j); int index2 = (nums1.size() + nums2.size() + 1 ) / 2 - index1; int max_left; if (index1 == 0 ) { max_left = nums2[index2 - 1 ]; } else if (index2 == 0 ) { max_left = nums1[index1 - 1 ]; } else { max_left = nums1[index1 - 1 ] > nums2[index2 - 1 ] ? nums1[index1 - 1 ] : nums2[index2 - 1 ]; } if ((nums1.size() + nums2.size()) % 2 == 1 ) { return max_left; } int min_right; if (index1 == nums1.size()) { min_right = nums2[index2]; } else if (index2 == nums2.size()) { min_right = nums1[index1]; } else { min_right = nums1[index1] < nums2[index2] ? nums1[index1] : nums2[index2]; } return (max_left + min_right) * 0.5f ; } double findMedianSortedArrays (vector <int >& nums1, vector <int >& nums2) { if (nums1.size() > nums2.size()) { return findMedianSortedArrays2(nums2,nums1); } else { return findMedianSortedArrays2(nums1, nums2); } } };
代码实现优化 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 137 138 class Solution {public : double findMedianSortedArrays (vector <int >& nums1, vector <int >& nums2) { int m = nums1.size(); int n = nums2.size(); int i = 0 ; int j = (m + n + 1 ) / 2 - i; int iMin = 0 , iMax = m; if (m == 0 ) { i = 0 ; j = (m + n + 1 ) / 2 ; } else if (n == 0 ) { i = (m + n + 1 ) / 2 ; j = 0 ; } else { while (iMin <= iMax) { i = (iMin + iMax) / 2 ; j = (m + n + 1 ) / 2 - i; if (j < 0 ) { iMax = i - 1 ; continue ; } else if (j > n) { iMin = i + 1 ; continue ; } if (i == m) { if (nums1[i - 1 ] <= nums2[j]) { break ; } else { iMax = i - 1 ; continue ; } } else if (i == 0 ) { if (nums1[i] >= nums2[j - 1 ]) { break ; } else { iMin = i + 1 ; continue ; } } if (j == n) { if (nums1[i] >= nums2[j - 1 ]) { break ; } else { iMin = i + 1 ; continue ; } } else if (j == 0 ) { if (nums1[i - 1 ] <= nums2[j]) { break ; } else { iMax = i - 1 ; continue ; } } if (nums1[i - 1 ] > nums2[j]) { iMax = i - 1 ; } else if (nums1[i] < nums2[j - 1 ]) { iMin = i + 1 ; } else { break ; } } } int max_left = 0 ; if (i == 0 ) { max_left = nums2[j - 1 ]; } else if (j == 0 ) { max_left = nums1[i - 1 ]; } else { max_left = nums1[i - 1 ] > nums2[j - 1 ] ? nums1[i - 1 ] : nums2[j - 1 ]; } if ((m + n) % 2 == 1 ) { return max_left; } int min_right = 0 ; if (i == m) { min_right = nums2[j]; } else if (j == n) { min_right = nums1[i]; } else { min_right = nums1[i] < nums2[j] ? nums1[i] : nums2[j]; } return (max_left + min_right) * 0.5f ; } };
有序数组第K小的元素 思路分析
通过求有序数组第K小的元素来求中位数
代码实现 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 class Solution {public : int findKSortedArraysBisection (vector <int >& nums1, vector <int >& nums2, int k) { int m = nums1.size(); int n = nums2.size(); int i = 0 ; int j = k - i; int iMin = 0 , iMax = m; if (m == 0 ) { i = 0 ; j = k; } else if (n == 0 ) { i = k; j = 0 ; } else { while (iMin <= iMax) { i = (iMin + iMax) / 2 ; j = k - i; if (j < 0 ) { iMax = i - 1 ; continue ; } else if (j > n) { iMin = i + 1 ; continue ; } if (i == m && j == n) { break ; } if (i == m) { if (nums1[i - 1 ] <= nums2[j]) { break ; } else { iMax = i - 1 ; continue ; } } else if (i == 0 ) { if (nums1[i] >= nums2[j - 1 ]) { break ; } else { iMin = i + 1 ; continue ; } } if (j == n) { if (nums1[i] >= nums2[j - 1 ]) { break ; } else { iMin = i + 1 ; continue ; } } else if (j == 0 ) { if (nums1[i - 1 ] <= nums2[j]) { break ; } else { iMax = i - 1 ; continue ; } } if (nums1[i - 1 ] > nums2[j]) { iMax = i - 1 ; } else if (nums1[i] < nums2[j - 1 ]) { iMin = i + 1 ; } else { break ; } } } int max_left = 0 ; if (i == 0 ) { max_left = nums2[j - 1 ]; } else if (j == 0 ) { max_left = nums1[i - 1 ]; } else { max_left = nums1[i - 1 ] > nums2[j - 1 ] ? nums1[i - 1 ] : nums2[j - 1 ]; } return max_left; } double findMedianSortedArrays (vector <int >& nums1, vector <int >& nums2) { int n = nums1.size(); int m = nums2.size(); if ((n + m) % 2 == 1 ) { return findKSortedArraysBisection(nums1,nums2,(n+m)/2 + 1 ); } else { return (findKSortedArraysBisection(nums1, nums2, (n + m) / 2 ) + findKSortedArraysBisection(nums1, nums2, (n + m) / 2 + 1 )) * 0.5f ; } } };