题目链接:Median of Two Sorted Arrays
这道题可以演变成一般的问题:给出两个Sorted Array, 求出第K小(大)的数。
在看这道题的时候,开始的思路是:既然是求中位值,我想着每次确定中位值左右相同的个数的sub array ,然后截取, 最后发现这种方法只能求中位数,而且判别条件很复杂,程序写起来容易出错,于是在网上查了些资料,存在一种可求第K小(大)数的一般方法,假设给出数组A , 数组B, 和顺序K,具体描述如下:
对任意pa + pb <= K,
若A[pa-1] >= B[pb-1], 截断B[0~pb-1], 问题转化成 给出数组A, 子数组B+pb(下一轮递归的数组B), 顺序K-pb(下一轮递归的K)
若A[pa-1] < B[pb-1], 截断A[0~pa-1], 问题转化成 给出子数组A+pa(下一轮递归的数组A), 数组B, 顺序K-pa(下一轮递归的K)
通常我们会取pa=pb=k/2
Ok, 那么问题来了,为什么可以截断数组? 这里面有一个本质问题,就是确保每一次被截断的序列不包含第K小(大)的数,这个网上证明有很多,不过都是直接取pa=pb=k/2;其实对任意pa + pb <= K 都成立。 下面给出AC代码:
class Solution{ protected: double findKthNum(int A[], int m, int B[], int n, int k){ if(m<n) return findKthNum(B, n, A, m, k); if(n==0) return A[k-1]; if(k==1) return min(A[0], B[0]); int pt = min(n-1, k/2-1); if(A[k/2-1] >= B[pt]) return findKthNum(A, m, B+pt+1, n-pt-1, k-pt-1); else return findKthNum(A+k/2, m-k/2, B, n, k-k/2); } public: double findMedianSortedArrays(int A[], int m, int B[], int n){ if((m+n)%2 == 0){ return (findKthNum(A, m, B, n,(m+n)/2) + findKthNum(A, m, B, n, (m+n)/2+1))/2; } else{ return findKthNum(A, m, B, n, (m+n)/2 + 1); } } };