Median of sorted arrays解题报告

来源:互联网 发布:程朱理学哲学思想知乎 编辑:程序博客网 时间:2024/06/05 21:49

题目链接
题意:

找出两个有序整数数组的中位数,要求时间复杂度是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

求中位数,也即求某个具体位置的值,所以可以转化为求两个排序数组中第k大的数。算法如下:

设两个序列分别为 A [ 1,..., m ] , B [ 1,..., n ] ,首先比较 A [ m / 2 ] 和 B [ n / 2 ] ,再根据比较结果进行判断,不失一般性,我们假设 A [ m / 2 ] ≥ B [ n / 2 ] ,再由 A , B 均有序可知, A [ m / 2 + 1,..., m ] 的所有元素肯定排在 A ∪ B 的 m / 2 + n / 2 名之后,而 B [ 1,..., n / 2 ] 肯 定 排 在 A ∪ B 的 m / 2 + n / 2 名 以 内 。 所 以 , 如 果k ≤ m / 2 + n / 2 ,就可以将 A [ m / 2 + 1,..., m ] 剔除掉,继续在剩余元素中寻找第 k小元素。如果 k > m / 2 + n / 2 ,那么就可以将 B [ 1,..., n / 2 ] 剔除掉,继续在剩余元素中寻找第 k − n / 2 大元素。于是可得以下递归式:⎧ T ( m , n ) = T ( m / 2, n ) + 1 if cond ...⎪⎨ T ( m , n ) = T ( m , n / 2 ) + 1 else⎪⎩ T ( 0, n ) = T ( m , 0 ) = O ( 1 )所以 T ( m , n ) = O ( log m + log n )

以上参考《算法概率》的Ex2.22的解法
复杂度:

log(m+n) < log m + log n < 2log(m+n)所以O(log m + log n)与O(log(m+n))等价

代码实现如下

class Solution {public:    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {        int size1 = nums1.size();        int size2 = nums2.size();        int n = size1 + size2;        if(n == 0){            return 0;        }        return (findKthElement(nums1.begin(),nums1.end(),nums2.begin(),nums2.end(),(n-1)/2) + findKthElement(nums1.begin(),nums1.end(),nums2.begin(),nums2.end(),n/2))/2;    }private:    typedef vector<int>::iterator it;    double findKthElement(it begin1, it end1, it begin2, it end2, int k) {        int size1 = end1 - begin1;        int size2 = end2 - begin2;        int med1 = size1 / 2;        int med2 = size2 / 2;        int n = med1 + med2 + 1;        int val1 = 0;        int val2 = 0;        if(size1 == 0){            return *(begin2 + k);        }        if(size2 == 0){            return *(begin1 + k);        }        val1 = *(begin1 + med1);        val2 = *(begin2 + med2);        if(val1 >= val2){            if(k >= n){                return findKthElement(begin1, end1, begin2 + med2 + 1, end2, k - med2 - 1);            }            else{                return findKthElement(begin1, begin1 + med1, begin2, end2, k);            }        }        else{            if(k >= n){                return findKthElement(begin2, end2, begin1 + med1 + 1, end1, k - med1 - 1);            }            else{                return findKthElement(begin2, begin2 + med2, begin1, end1, k);            }        }    }};