LeetCode题解(4)--Median of Two Sorted Arrays

来源:互联网 发布:unity3d 游戏版本号 编辑:程序博客网 时间:2024/06/16 20:44

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)).

example1

nums1 = [1, 3]nums2 = [2]The median is 2.0

example2

nums1 = [1, 2]nums2 = [3, 4]The median is (2 + 3)/2 = 2.5

解题思路

此题更通用的形式是求两个有序数组中第K大的数。
对于两个有序数组a[1…m], b[1…n],求两个数组合一起后第K大的数,假设m < n,在数组a中找到第k/2大的数ai,在数组b中找到第k-i大的数bj(不说k/2是为了避免k的奇偶造成的i+j不一定等于k的情况),i+j=k。(注意k/2可能大于m,若大于m,则用am代替ai,此时j=k-m)
i 和 j 将数组a,b分别划分为两部分,比较ai和bj的大小:
若ai > bj,说明第k大的数不可能出现在数组a的右部,也不可能出现在数组b的左部(用反证法可证),舍弃这部分,在a的左部(包含ai)和b的右部(不包含bj)中查找第k-j大的数。(因为此时b[1..j]必然在前k个数中)
若ai < bj,说明第k大的数不可能出现在数组a的左部,也不可能出现在数组b的右部(用反证法可证),舍弃这部分,在a的右部(不包含ai)和b的左部(包含bj)中查找第k-i大的数。(因为此时a[1..i]必然在前k个数中)
若ai = bj,说明第k大的数就是ai,可并入上述两种情况之一。

解题代码

C语言

#include <stdio.h>#define min(a,b) ((a) < (b)) ? (a) : (b)double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {    int len = nums1Size + nums2Size;    if(len & 0x1 == 1)        return findKthNum(nums1, nums1Size, nums2, nums2Size, len / 2 + 1);    else        return (findKthNum(nums1, nums1Size, nums2, nums2Size, len / 2) + findKthNum(nums1, nums1Size, nums2, nums2Size, len / 2 + 1)) / 2.0;}int findKthNum(int* nums1, int m, int* nums2, int n, int k) {    if(m > n)        return findKthNum(nums2, n, nums1, m, k);    if(m == 0)        return nums2[k - 1];    if(k == 1)        return min(nums1[0], nums2[0]);    int i = min(m, k/2);    int j = k - i;    if(nums1[i - 1] > nums2[j - 1])        return findKthNum(nums1, i, nums2 + j, n - j, k - j);    else        return findKthNum(nums1 + i, m - i, nums2, j, k - i);}int main(){    int nums1[] = {4, 5};    int nums2[] = {1, 2, 3, 6};    double re = findMedianSortedArrays(nums1, 2, nums2, 4);    printf("%f\n", re);    return 0;}

C++

#include <iostream>#include <vector>using namespace std;class Solution {public:    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2){        int m = nums1.size();        int n = nums2.size();        int len = m + n;        if(len & 0x1 == 1)            return findKthNum(nums1, 0, m, nums2, 0, n, len/2 + 1);        else            return (findKthNum(nums1, 0, m, nums2, 0, n, len/2) + findKthNum(nums1, 0, m, nums2, 0, n, len/2 + 1)) / 2.0;    }    int findKthNum(vector<int>& nums1, int beg1, int m, vector<int>& nums2, int beg2, int n, int k){        if(m > n)            return findKthNum(nums2, beg2, n, nums1, beg1, m, k);        if(m == 0)            return nums2[k-1];        if(k == 1)            return min(nums1[beg1], nums2[beg2]);        int i = min(m, k/2);        int j = k - i;        if(nums1[beg1 + i - 1] > nums2[beg2 + j - 1])            return findKthNum(nums1, beg1, i, nums2, beg2 + j, n - j, k - j);        else            return findKthNum(nums1, beg1 + i, m - i, nums2, beg2, j, k - i);    }};int main(){    vector<int> a,b;    a.push_back(4);    a.push_back(5);    b.push_back(1);    b.push_back(2);    b.push_back(3);    b.push_back(6);    Solution s;    double re = s.findMedianSortedArrays(a,b);    cout<<re<<endl;    return 0;}