leetcode4 寻找两个正序数组的中位数(Hard)

题目来源:leetcode4 寻找两个正序数组的中位数

题目描述:

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。

请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

则中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

解题思路:

结合二分法。

在两个排序数组中找中位数,数组长度m和n ,求left=(m+n+1)/2和right=(m+n+2)/2位置的值的平均数,可以把问题简化不用考虑奇数偶数。

接着把问题转为为在数组中找第k大的数(k分别为left和right),可以在nums1数组和nums2数组中分别找前k/2个数,如果其中一个第k/2个数小于另一个的第k/2个数,那么第k大数肯定在另一个里面,那么把第k大数不在的数组砍掉k/2,再继续寻找,即每次缩小k/2范围,每次折半删除的都是比第k个数小的,最终找到第k个数。

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m=nums1.size(),n=nums2.size(),left=(m+n+1)/2,right=(m+n+2)/2;
        return (findKth(nums1,0,nums2,0,left)+findKth(nums1,0,nums2,0,right))/2.0;
    }
    int findKth(vector<int> nums1,int i,vector<int> nums2,int j,int k){
        if(i>=nums1.size()) return nums2[j+k-1];
        if(j>=nums2.size()) return nums1[i+k-1];
        if(k==1) return min(nums1[i],nums2[j]);
        int midVal1=(i+k/2-1)<nums1.size()?nums1[i+k/2-1]:INT_MAX;
        int midVal2=(j+k/2-1)<nums2.size()?nums2[j+k/2-1]:INT_MAX;
        if(midVal1<midVal2)
            return findKth(nums1,i+k/2,nums2,j,k-k/2);
        else return findKth(nums1,i,nums2,j+k/2,k-k/2);
        
    }
};
posted @ 2020-07-01 16:15  拉里拉里啦啦  阅读(566)  评论(0编辑  收藏  举报