Median of Two Sorted Arrays(求中位数)

ACM题集:https://blog.csdn.net/weixin_39778570/article/details/83187443

题目链接
题目大意:从俩个排序好的数组里找到这两个数组的中位数,时间复杂度为 O(log (m+n)),m,n为两数组长度

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
这里写图片描述
这里写图片描述
为什么i是在小的数组里呢?因为如果i是在大的数组里的话,那么算出来的j可能会是负数。

博主刚学c++代码写得很差

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        vector<int> A = nums1;
        vector<int> B = nums2;
        // 交换数组,A为长度小的数组,B为长度大的数组
        if(A.size() > B.size()){
		    vector<int> t = B;
		    B = A;
		    A = t;
	    }
 
    	int n = A.size(), m = B.size();
    	if(n==0){
	    	if(m%2==1){
	    		return (double)B[(m-1)/2];
	    	}else{
		    	return (double)(B[(m-1)/2] + B[(m-1)/2+1])/2.0;
	    	}
	    }
	    int iMin = 0;
    	int iMax = n;
    	double LMAX = 0, RMIN = 0;
    	// 二分查找i
    	while(iMin <= iMax){
    		int i = iMin + (iMax-iMin)/2;
    		int j = (m+n+1)/2-i;
    		// 存在临界情况即一整个数组在一边
    		if((i==n || j==0 || A[i]>=B[j-1])
    		&& (j==m || i==0 || B[j]>=A[i-1])){
    			if(i==0){
    				LMAX = B[j-1];
	    		}else if(j==0){
    				LMAX = A[i-1];
    			}else{
    				LMAX = max(A[i-1], B[j-1]);
    			}
    			
    			if(i==n){
    				RMIN = B[j];
    			}else if(j==m){
    				RMIN = A[i];
    			}else{
    				RMIN = min(A[i], B[j]);
    			}
    			break;
    		}else if(i>0 && A[i-1] > B[j]){
    			iMax = i-1;
    		}else if(j>0 && B[j-1] > A[i]){
    			iMin = i+1;
    		}
    	}
    	if((n+m)%2==0){
    		return (double)(LMAX+RMIN)/2.0 ;
    	}else{
	    	return LMAX;
    	}
    }
};

二进制问题half = (iMin+iMax)/2 == iMin + (iMax-iMin)/2 == iMin&iMax + (iMin^iMax)>>1;
可以理解过iMax和iMin的和为n, n的一半等于 a + (b-a)/2 (a+b==n, && a<=b)
举个例子a+b=9, 4 == 9/2 == 2+(7-2)/2 == 1+(8-1)/2 == 3+(6-3)/2
iMin&&iMax + (iMin^iMax)>>1 的原理差不多就是这样。
一份23ms的优秀提交(别人的)

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size(), n = nums2.size();
        if (m > n) return findMedianSortedArrays(nums2, nums1);
        int i, j, imin = 0, imax = m, half = (m + n + 1) / 2;
        while (imin <= imax) {
            i = (imin & imax) + ((imin ^ imax) >> 1);
            j = half - i;
            if (i > 0 && j < n && nums1[i - 1] > nums2[j]) imax = i - 1;
            else if (j > 0 && i < m && nums2[j - 1] > nums1[i]) imin = i + 1;
            else break;
        }
        int num1;
        if (!i) num1 = nums2[j - 1];
        else if (!j) num1 = nums1[i - 1]; 
        else num1 = max(nums1[i - 1], nums2[j - 1]);
        if ((m + n) & 1) return num1;
        int num2;
        if (i == m) num2 = nums2[j];
        else if (j == n) num2 = nums1[i];
        else num2 = min(nums1[i], nums2[j]);
        return (num1 + num2) / 2.0;
    }
};

// 加上这个可以提高io速度

static const auto _____ = []()
{
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        return nullptr;
 }();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值