红桃J

用心写好每行完美的代码,远比写一堆更有价值

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

这题真是浪费了很多时间,想法也对了,转移到寻找第k小的元素上来,然后根据两个都是一排好序的数组,像类似算法导论中利用partition找到划分的q,但在这里,由于题目要求O(logn),所以这个找q的过程必须是常数时间,想了好久想不到一个常数时间的划分。最后在网上找到答案了:
分析:我们现在设计一个求第k小元素的算法,为了分析方便我这里假使数组的下标是从1开始的。现在先假设数组A,B的元素个数都大于k/2个(为了好分析先这样假设,具体会有不同),现在我们找出A中的第k/2个元素,B中的第k-k/2个元素,比较A[k/2]和B[k-k/2]。

假如:A[k/2]<B[k-k/2],那么其实我们可以把比A[k/2]小及A[k/2]都去掉,因为A[k/2]肯定比第k小的元素小。下面我么来说明一下这一点:假如A[k/2]是第k小,或比第k小大,B[k-k/2]肯定是第k-k/2小的在B中,所以B中比A[k/2]小的最多就k-k/2-1个,A中比A[k/2]小的最多就k/2-1个,那么A,B加起来比A[k/2]小的最多就k/2-1+k-k/2-1=k-2个,也就是说A最大只可能是第k-1小,所以我们可以抛弃A[k/2]及其左边的A中的元素。那么问题就转化为求A[k/2+1,……,m]和B[1,……,n]中第k-k/2小的元素了。

假如:A[k/2]>B[k-k/2],问题就转化为求A[1,……,m]和B[k-k/2+1,……n]中第k-(k-k/2)小的问题了。

假如:A[k/2]=B[k-k/2],那么在A中有k/2-1个比A[k/2]小的在B中也有k-k/2-1个比A[k/2]小的,所以A[k/2]是第k-1小的元素,但B[k-k/2]和A[k/2]一样大,所以A[k/2]也可以说是第k小的元素。

那么我们现在来讨论一下边界情况:假如k/2比m大,我们就选取A[m]和B[k-m]进行比较,依然可以比较出来,这时如果A[m]比B[k-m]小那么就返回B[k-m]就行了,它就是第k小元素。其他情况类似上边的讨论。

代码:

 

 1 #include<iostream>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 
 6 double FindKth(int a[], int m, int b[], int n, int k)
 7 {
 8     if (m < n)
 9     {
10         return FindKth(b, n, a, m, k);
11     }
12     if (m == 0)
13         return b[k-1];
14     if (k == 1)
15         return min(a[0], b[0]);
16     int pa = min(k / 2,m);
17     int pb = k - k / 2;
18     if (a[pa - 1] < b[pb - 1])
19         return FindKth(a + pa, m - pa, b, n, k - pa);
20     else if (a[pa - 1]>b[pb - 1])
21         return FindKth(a, m, b + pb, n - pb, k - pb);
22     else
23         return a[pa - 1];
24 }
25 
26 double MedianOfTwoSortedArrays(int a[], int m, int b[], int n)
27 {
28     int total = m + n;
29     if (total % 2 == 1)
30         return FindKth(a, m, b, n, total / 2 + 1);
31     else
32         return (FindKth(a, m, b, n, total / 2) + FindKth(a, m, b, n, total / 2 + 1))/2;
33 }
34 
35 int main()
36 {
37     int a[] = { 1, 2, 4,5};
38     int b[] = { 3, 5, 6, 7 };
39     cout << MedianOfTwoSortedArrays(a, 4, b, 4) << endl;
40 }

 

posted on 2015-03-04 13:34  红桃J  阅读(142)  评论(0编辑  收藏  举报