Leetcode 4-寻找两个有序数组的中位数(hard)

题目描述

给定两个大小为 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

步骤:

1.先确保m<=n,如果不满足 就把两者都交换(目的是为了使后面j总是>=0)

2.i作为nums1的标记,j作为nums2的标记,用halflen表示两个数组拼起来的一半长度,分为左边一半和右边的一半。

3.为了求中位数,那么就需要左边一半的max小于右边一半的min。如果nums1[i-1]>nums2[j],这里为保证两半长度是一样的,i就要增大,j相应的减小(这样把nums1中大的数放到右边,nums2的小的数放到左边,通过移动 i 这个标记来实现这个操作)。如果nums[j-1]>nums1[i],同理就是j要增大而i减小。

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m=nums1.size(),n=nums2.size();
        if(m==0)
        {
        	if(n%2==1)
        		return nums2[n/2];
			return (nums2[n/2]+nums2[n/2-1])/2.0; 
		}
        if(n==0)
        {
                if(m%2==1)
        		return nums1[m/2];
			return (nums1[m/2]+nums1[m/2-1])/2.0; 
        }
        if(m>n)  //为了保证m<=n,如果m>n,就让两者交换 
        {
        	vector<int> num;
        	num=nums1;nums1=nums2;nums2=num;
        	int temp;
        	temp=m;m=n;n=temp;
		}
		int imin=0,imax=m, halflen=(m+n+1)/2;
		int lmax=0,rmin=0;
		while(imin<=imax)
		{
			int i=(imin+imax)/2;  //nums1的标记 
			int j=halflen-i;      //nums2的标记 
			if(i<m & nums2[j-1]>nums1[i])
			{
				imin=i+1;  
			}
			else if(i>0 & nums1[i-1]>nums2[j])
				imax=i-1;
			else
			{
				if(i==0)
					lmax=nums2[j-1];
				else if(j==0)
					lmax=nums1[i-1];
				else
					lmax=max(nums1[i-1],nums2[j-1]);
				
				if((m+n)%2==1)
					return lmax;
				
				if (i==m)
					rmin=nums2[j];
				else if(j==n)
					rmin=nums1[i];
				else
					rmin=min(nums1[i],nums2[j]);
				return (lmax+rmin)/2.0;
			}
		}
    }
};

方法二:这个思路更简单了

这个方法先建立一个res数组,

将小的数先放入res中,当其中一个数组中的数都放完了之后,把另一个数组中未存入的数组补齐放入res中

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m=nums1.size(),n=nums2.size();
        if(m==0)
        {
            if(n%2==1)
        		return nums2[n/2];
			return (nums2[n/2]+nums2[n/2-1])/2.0;
        }
        if(n==0)
        {
            if(m%2==1)
        		return nums1[m/2];
			return (nums1[m/2]+nums1[m/2-1])/2.0; 
        }
        vector<int> res;
		int i=0,j=0;
		while(i<m&&j<n)  //将小的数先存入res中
		{
			if(nums1[i]<=nums2[j])
			{
				res.push_back(nums1[i]);
				i++;}	
			else
			{
				res.push_back(nums2[j]);
				j++;}	
		}
		while(i<m)   //也就是当经过上述j=n后,如果nums1中的数组还未存放完继续放入res中
		{
			res.push_back(nums1[i]);
			i++;
		}
		while(j<n)
		{
			res.push_back(nums2[j]);
			j++;
		}
		int len=m+n;
		if(len%2==1)
			return res[len/2]*1.0;
		else
			return (res[len/2]+res[len/2-1])/2.0;
    }
};

猜你喜欢

转载自blog.csdn.net/Mr_xuexi/article/details/84979095