【Leetcode】Median of Two Sorted Arrays

来源:互联网 发布:微小宝类似软件 编辑:程序博客网 时间:2024/06/03 22:41

问题:

There are two sorted arrays A and B 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)).

代码:

//  mo2sa.cpp//  Test////  Created by mac on 5/19/14.//  Copyright (c) 2014 mac. All rights reserved.//#include "mo2sa.h"#include <iostream>using namespace std;double findKth(int A[], int m, int B[], int n , int k){        cout<<"A[0] = " << A[0] <<","<< "m = " <<m<<","<<"B[0] ="<<B[0]<<","<<"n = "<<n<<","<<"k = "<<k<<endl;        if (m > n) {        return findKth(B , n , A , m , k );    }        if(m == 0)        return B[k-1];            if (k == 1) {        return min(A[0] , B[0]);    }        int pa = min(k / 2, m), pb = k - pa;    if (A[pa - 1] < B[pb-1]) {        /* 0  -  A[k/2 - 1]is useless */        return findKth(A + pa, m - pa, B, n, k - pa);    }    else if(A[pa - 1] > B[pb - 1]){        /* 0 - B[k/2 -1 ] is useless */        return findKth(A, m, B + pb, n - pb, k - pb);    }    else{        return A[pa-1];    }    }class Solution {public:    double findMedianSortedArrays(int A[], int m, int B[], int n) {        int total = m + n;        if (total % 2 == 0) {            /* total is even  */            return (findKth(A , m , B , n , total /2 ) + findKth(A , m , B , n , (total /2) + 1))/2;        }        else{            /* total is odd  */            return findKth(A , m , B , n , total /2 );        }    }};int main(){    Solution s;    int a[] = {1,3,4,5,7,12,45,56,67,78,89,100};    int b[] = {2,4,23,34,45,50,51,52,53,67,68,69};    cout<<"result :"<<endl<<s.findMedianSortedArrays(a, sizeof(a)/sizeof(int), b, sizeof(b)/sizeof(int))<<endl;}


分析:

这个问题比较绕,大家都能够想到的算法是归并算法,算法复杂度威O(N),但显然不满足题目要求。

O(log(N)) 这个复杂度稍微有些难度,我也是看了别人的想法才能够做出这道题,反正也学到了。

分析看这里:但我觉得说的比较不清楚。

http://blog.csdn.net/yutianzuijin/article/details/11499917

找到第K大的数据算法原理,我的重新理解:

1. 保证A的元素小于B的元素个数(待会解释为什么要保证这点)

2. 把A折半,与B中的第<K-(k/2)>(假设是第J个数字)数字比较,此时B的第J个数字肯定小于B元素个数/2 个元素,原因是B>A, 自然 B/2 > A>2咯,参考1.

3. 这里是重点:

a.如果A中间的数比B的第J个数小,那A[0]-A[k/2-1] 都没有意义,中数肯定不在那里面,原因是A有k/2(或者m个)的数据比B的第J个数字小,且B中有J个(k/2或者,K-m)个数据比B的第J个数字小,两者相加,有k个数字比B[J] 小,则不可能在这段范围之内。因为咱们就是要照第k个数,但这里却证明,第已经穷举了k个数小于一个数字。

b 如果A中间的数比B[J] 大,则说明B[0]-B[J] 没有任何意义了,原因和a类似。这里解释一下为啥都小于A的中数,为啥不丢弃A的前半部分呢?原因是B[J] 小于A的中数,比A大的数还可能有可能是最终的第K个数,毕竟比B[J]大的数不是一定比A中数大。a类似。

c 倘若他们相等了,则随便选择一个返回即可:A中间的数字,或者B[J], 理由是他们的前半部分加起来是k,所以他们两个绝对是了,不用考虑了。

d,然后递归。

4.关于前面几个判定条件的解释:

a.  m == 0 , 此时返回B 的第k个数,因为A已经没有数字了,第K个数字肯定再B中咯。

b. k == 1  , 只有一个名额了,那么A,B中谁小,谁就返回呗,最小的肯定是第一个。

c. m > n 这样是为了保证 A 个数永远小雨B的个数。原因上面有交代。

总结:

算法还需要多练。


0 0