[array] leetCode-4-Median of Two Sorted Arrays-Hard
2017-11-11 00:11
471 查看
leetCode-4-Median of Two Sorted Arrays-Hard
descrition
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)).
example 1
nums1 = [1, 3] nums2 = [2] The median is 2.0
example 2
nums1 = [1, 2] nums2 = [3, 4] The median is (2 + 3)/2 = 2.5
解析
注意题目对时间复杂度的要求:O(log (m+n)),在加上数组有序的条件,此处应该联想到二分搜索的优化。那要如何用呢?看下面分析。(也可以参考 leetcode 中的 solution,解释得也很好)定义函数接口:
double findMedianSortedArrays(vector<int>& A, vector<int>& B)
即两个数组 A, B,假设大小分别为 m 和 n
将数组 A 根据任意位置 i 分成左右两部分,同理 B 根据任意位置 j 也分成左右两部分,如下:
left_part | right_part A[0], A[1], ..., A[i-1] | A[i], A[i+1], ... , A[m] B[0], B[1], ..., B[j-1] | B[j], B[j+1], ... , B
由中位数的定义以及数组有序的条件,我们希望以上划分满足:
len(left_part) = len(right_part) ==> i+j = m-i + n-j (or: i+j = m-i + n-j + 1 (奇数的情况,将多的一个放到左边)) ==> j = (m+n+1)/2 - i, i=[0,m] max(left_part) <= min(right_part) ==> A[i-1] <= B[j] && B[j-1] <= A[i]
由此我们只需要在有序数组 A 上进行二分查找,确定 i 的位置,使得以上条件满足即可找到合适的划分。在此基础上我们可以根据划分边界求得 median。
初始条件:imin = 0, imax = m; 当 imin <= imax 时候的一次迭代: i = (imin + imax) / 2 j = (m+n+1)/2 - i // 此处讨论暂时不考虑边界情况,即假设 i 和 j 都合法 // 只可能出现以下几种情况: (1) A[i-1] <= B[j] && B[j-1] <= A[i] // 划分满足要求,可以停止循环 (2) A[i-1] > B[j] // A[i-1] 太大,也就是我们要想办法调整 i 的值使得 A[i-1] <= B[j] 成立 // 这个时候如果我们增大 i,只会使得 A[i-1] 更大 (因为数组是非递减有序的) // 因此我们只能通过减小 i,尝试找到更小的 A[i-1],因此作出如下调整 imax = i-1 (3) B[j-1] > A[i] // B[j-1] 太大,同理我们应该减小 j // 从另一个角度,减小 j 就相当于增大 i,因此我们作出以下调整 imin = i+1
几个细节:
m <= n 必须成立。因为 j = (m+n+1)/2 - i,如果 m>n,那么 j 将有可能为负数。因此在程序的开始进行检查。
边界条件的讨论。当 i==0, j==0, i==m, j==n 时,A[i-1], B[j-1], A[i], B[j] 都是不成立的。如果 i 和 j 都满足要求时,我们需要检查 A[i-1] <= B[j] && B[j-1] <= A[i] 是否成立,那么当 i 和 j 到达边界条件时,我们也就不需要检查其中的某一个条件,比如当 i == 0 时, A 数组的左边为空,我们就不需要检查 A[i-1] <= B[j] 这个条件。(参看代码)
code
#include <iostream> #include <vector> #include <algorithm> using namespace std; class Solution{ public: double findMedianSortedArrays(vector<int>& A, vector<int>& B){ // insure the size of A is less than and equal to the size of B if(A.size() > B.size()) swap(A, B); int m = A.size(); int n = B.size(); // m <= n // when m+n is odd, the follow equation will insure the median // will be assined into left part. int lenLeft = (m+n+1) / 2; // binary search int imin = 0, imax = m; while(imin <= imax){ int i = (imin + imax) / 2; int j = lenLeft - i; if( i>0 && A[i-1] > B[j]){ // A[i-1] too large, decreasing i // i > 0 ==> j<n, because j = (m+n+1) / 2 - i < (m+n+1) / 2 < 2n+1/2 < n imax = i-1; }else if ( i<m && B[j-1] > A[i]){ // A[i] too small, increasing i // i < m ==> j>0, because j = (m+n+1) / 2 - i > (m+n+1) / 2 - m > (2m+1)/2 - m > 0 imin = i+1; }else{ // perfit int maxLeft = 0; if(i == 0){ maxLeft = B[j-1]; }else if (j == 0){ maxLeft = A[i-1]; }else{ maxLeft = max(B[j-1], A[i-1]); } if( ((n+m)&1) == 1) // odd return maxLeft; int minRight = 0; if(i == m){ minRight = B[j]; }else if (j == n){ minRight = A[i]; }else{ minRight = min(B[j], A[i]); } return (maxLeft + minRight)*1.0 / 2.0; } } return 0.0; } }; int main() { return 0; }
相关文章推荐
- 【leetcode】Array—— Median of Two Sorted Arrays(4)
- leetcode.array--4. Median of Two Sorted Arrays
- LeetCode刷题(C++)——Median of Two Sorted Arrays(Hard)
- LeetCode第四关:Median of Two Sorted Arrays --> Difficulty: Hard
- 【leetcode】Median of Two Sorted Arrays(hard)★!!
- LeetCode4/88 Median of Two Sorted Arrays/Merge Sorted Array
- LeetCode:4_Median of Two Sorted Arrays | 求两个排序数组的中位数 | Hard
- 算法分析与设计丨第三周丨LeetCode(5)——Median of Two Sorted Arrays(Hard)
- LeetCode题解-----Median of Two Sorted Arrays
- leetcode 4-Median of Two Sorted Arrays
- leetcode 4. Median of Two Sorted Arrays
- LeetCode4 Median of Two Sorted Arrays
- leetcode-004:Median of Two Sorted Arrays
- [LeetCode][JavaScript]Median of Two Sorted Arrays
- 【LeetCode】median of two sorted arrays
- LeetCode-Median of Two Sorted Arrays
- [leetcode]median of two sorted arrays【寻找第k小的数问题】
- LeetCode之Median of Two Sorted Arrays
- leetcode004:Median of Two Sorted Arrays
- leetcode之 median of two sorted arrays