leetcode之Median of Two Sorted Arrays

原题如下:

There are two sorted arrays A and B 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)).

这道题是找两个有序数组的中位数,目前想到的办法是首先将两个有序数组归并成一个有序数组,然后返回归并后的中位数即可,但这种方法的时间复杂度时O(m + n),O(log(m + n))的算法稍后研究下吧。

class Solution {
public:
    double findMedianSortedArrays(int A[], int m, int B[], int n) {
		int *temp = new int[m + n];
		merge(A,m,B,n,temp);
		if((m + n) % 2 == 0)
			return (temp[(m + n) / 2] + temp[(m + n) / 2 - 1]) / 2.0;
		else
			return temp[(m + n) / 2];

    }
	void merge(int A[], int m, int B[], int n, int temp[]){
	    int i = 0, j = 0, k = 0;
		while(i < m && j < n){
			if(A[i] < B[j])
				temp[k++] = A[i++];
			else
				temp[k++] = B[j++];
		}
		while(i < m)
			temp[k++] = A[i++];
		while(j < n)
			temp[k++] = B[j++];
	}
};

补(2014.06.12)

下面补充下O(log(m + n))的解法,显然在有序的情况下查找效率最高的是二分查找,此题也一样,当 m + n 为奇数时,寻找的即是第 (m + n)/2 + 1个数,而当m + n 为偶数时,寻找的是第(m + n)/2个数和第(m + n)/2 + 1个数的平均值,所以此题更一般的解法是寻找第k个数。按照二分查找的思路,分别在两个数组中查找第k/ 2个元素,当这两个元素相等时,即是寻找的第k个数,当A中第k/2个元素小于B中第k/2个元素时,则舍弃A中前k/2个元素,否则舍弃B中k/2个元素,然后依次递归。这里需要注意的特殊情况比较多,首先是当数组长度小于k/2时,需要选择其数组中最后一个元素,然后再据此确定较长数组中要查找的元素,所以在代码中总是假设A数组总是小于B数组的长度。其次是当一个数组长度为0时,直接返回第二个数组中第k个元素。还有就是当k等于1时返回两个数组中首元素较小的元素。可见,这种方法需要注意的细节特别多。。。

double findMedianSortedArrays(int A[], int m, int B[], int n) {
	    int len = m + n;
		if(len % 2 == 0)
			return (findKthElem(A,m,B,n,len / 2) + findKthElem(A,m,B,n,len / 2 + 1)) / 2.0;
		else
			return findKthElem(A,m,B,n,len / 2 + 1);
	}
	double findKthElem(int *A,int m,int *B,int n,int k){  //m,n 为数组长度,k从1开始
	    if(m > n)
			return findKthElem(B,n,A,m,k);   //总是使m小于n
		if(m == 0)
			return B[k - 1];
		if(k == 1)
			return min(A[0],B[0]);		
		int pa = min(k / 2,m);
		int pb = k - pa;
		if(A[pa - 1] < B[pb - 1])
			return findKthElem(A + pa,m - pa,B,n,k - pa);
		else if(A[pa - 1] > B[pb - 1])
			return findKthElem(A,m,B + pb,n - pb,k - pb);
		else
			return A[pa - 1];
	}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值