Median of Two Sorted Arrays

来源:互联网 发布:java编程技巧 编辑:程序博客网 时间:2024/06/03 14:13

问题描述

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

算法分析

考察例子:

 nums1[5]:  1   3   5   7   9 
nums2[7]: 2 4 6 8 10 12 14

1、题目要求算法复杂度为log(m+n) ,所以肯定不能考虑合并这两个数组;

2、考虑二分查找,考虑到已经排序,令k=(5+7)/2+1 ,比较nums1[k/2 - 1]nums2[k-k/2-1] 的大小,在这里即nums1[2]<nums2[3] ,所以中位数肯定不在nums[2] 的前一段。下一次就可以在nums1[3:5]nums2[0:7] 中查找,同时可以确定找到三个数nums[0:2] 小于中位数,故更新k=k-3;

3、k可以理解为比中位数小的数的数量,每次数组的一段被排除,这一段即小于中位数。k大于1的时候递归上述查找过程,当k等于1的时候,比中位数小的数的数量达到,即找到中间值。

*值得注意的是,两个数组的长度之和为偶数时,需要查找得到两个中位数,取平均。
这里写图片描述

C++实现

class Solution {    typedef vector<int>::iterator Iter;    int findMedianCore(Iter start1, int len1, Iter start2, int len2, int k) {        if (len1 > len2)            return findMedianCore(start2, len2, start1, len1, k);        if (len1 == 0)            return *(start2 + k - 1);        if (k == 1)            return min(*start1, *start2);        int i1 = min(len1, k / 2);        int i2 = k - i1;        if ( *(start1 + i1 - 1) > *(start2 + i2 - 1) )            return findMedianCore(start1, len1, start2 + i2, len2 - i2, k - i2);        return findMedianCore(start1 + i1, len1 - i1, start2, len2, k - i1);    }public:    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {        int len1 = nums1.size();        int len2 = nums2.size();        if (!len1 && !len2)            return 0;        int k = (len1 + len2) / 2;        int result1 = findMedianCore(nums1.begin(), len1, nums2.begin(), len2, k + 1);        if ((len1 + len2) % 2 == 0) {            int result2 = findMedianCore(nums1.begin(), len1, nums2.begin(), len2, k);            return (double) (result1 + result2) / 2;        }        return result1;    }};

算法复杂度为O( log(m+n) ).