LeetCode题解——4Median of Two Sorted Arrays

Median of Two Sorted Arrays

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

1.merge O(n+m)

2.kth smallest of sorted array

不是一般性,认为数组a的长度m大于数组b的长度n,假设需要找到第k大的数,

  if (m < n) return kth(b,n,a,m,k);

三种边界情况

        if (n==0) return a[k-1];
        if (k==1) return min(a[0],b[0]);
	if (k==m+n)  return (a[m - 1] > b[n - 1])?a[m - 1]:b[n - 1];
其他:

从B数组入手,因为B数组有序,我们尝试用二分法进行;取B[j], j = min(n,k/2), 对于数组A中,取A[i] i = k -j;//(i+j)=k;

如果说A[i-1] > B[j-1]时 ,那么比A[i-1]小的数至少有A中的 i-1个 和B中的 j个,又因为 i+j =k;所以第k小的数不可能是A[i-1]后面的数A[i] .....A[m-1](因为至少大于A[0].....A[i-1]和B[0].....B[j-1]共K个数),也不可能是B[j-1]前面的数B[0].....B[j-2](因为最多大于A[0].....A[i-2]和B[0]......B[j-2]共k-2个数,所以不可能为第k小的数);

所以第k小的数只能是在A[0].....A[i-1]以及B[j]......B[n-1]之中,此时在这之中需要找第  k -j小的数,因为已经扔掉了 B[0]....B[j-1] j个前k小的数。


如果说A[i-1] < B[j-1]时 ,那么比B[j-1]小的数至少有A中的 i个 和B中的 j-1个(A[0].....A[i-1]和B[0]....B[j-2]),又因为 i+j =k;所以第k小的数不可能是B[j-1]后面的数B[j] .....B[n-1](因为至少大于A[0].....A[i-1]和B[0].....B[j-1]共K个数),也不可能是A[i-1]前面的数A[0].....A[i-2](因为最多大于A[0].....A[i-2]和B[0]......B[j-2]共k-2个数,所以不可能为第k小的数);

所以第k小的数只能是在B[0].....B[j-1]以及A[i]......A[m-1]之中,此时在这之中需要找第  k -i小的数,因为已经扔掉了 A[0]....A[i-1] j个前k小的数。


具体实现如下:

class Solution {
public:
    int kth(int a[], int m, int b[], int n, int k) {
        if (m < n) return kth(b,n,a,m,k);
        if (n==0) return a[k-1];
        if (k==1) return min(a[0],b[0]);
	if (k==m+n)  return (a[m - 1] > b[n - 1])?a[m - 1]:b[n - 1];

        int j = min(n,k/2);
        int i = k-j;
        if (a[i-1] > b[j-1]) return kth(a,i,b+j,n-j,k-j);
        return kth(a+i,m-i,b,j,k-i);
    }

    double findMedianSortedArrays(int a[], int m, int b[], int n) {
        int k = (m+n)/2;
        int m1 = kth(a,m,b,n,k+1);
        if ((m+n)%2==0) {
            int m2 = kth(a,m,b,n,k);
            return ((double)m1+m2)/2.0;
        }
        return m1;
    }
};


用vector实现:

class Solution {
public:
	double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
		int m = nums1.size();
		int n = nums2.size();
		int k = (m+n)/2;
		int m1 = kth(nums1,0,m-1,nums2,0,n-1,k+1);
		if ((m+n)%2==0) {
			int m2 = kth(nums1,0,m-1,nums2,0,n-1,k);
			return ((double)m1+m2)/2.0;
		}
		return m1;
	}
	int kth(vector<int> a,int al, int ar, vector<int> b, int bl, int br,int k) {
		if(ar - al <0 ) return b[bl+k-1];
		if(br - bl <0 ) return a[al+k-1];
		int m = ar - al + 1;
		int n = br - bl + 1;
		if (m < n) return kth(b,bl,br,a,al,ar,k);
		if (n==0) return a[k-1];
		if (k==1) return min(a[al],b[bl]);
		if (k==m+n)  return (a[ar] > b[br])?a[ar]:b[br];

		int j = min(n,k/2);
		int i = k-j;
		if (a[i-1 + al] == b[j-1 + bl])
			return a[i-1 + al];
		if (a[i-1 + al] > b[j-1 + bl]) 
			return kth(a,al,i-1+al,b,j+bl,br,k-j);
		return kth(a,al+i,ar,b,bl,j-1+bl,k-i);
	}
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值