LeetCode:Median of Two Sorted Arrays

Median of Two Sorted Arrays:

分析
这是一道非常经典的题。这题更通用的形式是,给定两个已经排序好的数组,找到两者所有元
素中第k 大的元素。
O(m + n) 的解法比较直观,直接merge 两个数组,然后求第k 大的元素。
不过我们仅仅需要第k 大的元素,是不需要“排序”这么复杂的操作的。可以用一个计数器,
记录当前已经找到第m 大的元素了。同时我们使用两个指针pA 和pB,分别指向A 和B 数组的第
一个元素,使用类似于merge sort 的原理,如果数组A 当前元素小,那么pA++,同时m++;如果
数组B 当前元素小,那么pB++,同时m++。最终当m 等于k 的时候,就得到了我们的答案,O(k)
时间,O(1) 空间。但是,当k 很接近m + n 的时候,这个方法还是O(m + n) 的。
有没有更好的方案呢?我们可以考虑从k 入手。如果我们每次都能够删除一个一定在第k 大元
素之前的元素,那么我们需要进行k 次。但是如果每次我们都删除一半呢?由于A 和B 都是有序
的,我们应该充分利用这里面的信息,类似于二分查找,也是充分利用了“有序”。
假设A 和B 的元素个数都大于k/2,我们将A 的第k/2 个元素(即A[k/2-1])和B 的第k/2
个元素(即B[k/2-1])进行比较,有以下三种情况(为了简化这里先假设k 为偶数,所得到的结
论对于k 是奇数也是成立的):
• A[k/2-1] == B[k/2-1]
• A[k/2-1] > B[k/2-1]
• A[k/2-1] < B[k/2-1]
如果A[k/2-1] < B[k/2-1],意味着A[0] 到A[k/2-1 的肯定在A [ B 的top k 元素的范围
内,换句话说,A[k/2-1 不可能大于A [ B 的第k 大元素。
因此,我们可以放心的删除A 数组的这k/2 个元素。同理,当A[k/2-1] > B[k/2-1] 时,可
以删除B 数组的k/2 个元素。
当A[k/2-1] == B[k/2-1] 时,说明找到了第k 大的元素,直接返回A[k/2-1] 或B[k/2-1]
即可。
因此,我们可以写一个递归函数。那么函数什么时候应该终止呢?
• 当A 或B 是空时,直接返回B[k-1] 或A[k-1];
• 当k=1 是,返回min(A[0], B[0]);
• 当A[k/2-1] == B[k/2-1] 时,返回A[k/2-1] 或B[k/2-1]


代码:

class Solution {
public:
    double findMedianSortedArrays(int A[], int m, int B[], int n) 
	{
		if ((m+n)%2==1)
		{
			return FindByIndex(A,m,B,n,(m+n)/2+1);
		}
		else
		{
			double a=FindByIndex(A,m,B,n,(m+n)/2)/2;
			double b=FindByIndex(A,m,B,n,(m+n)/2+1)/2;
			return a+b;
		}
    }
	double FindByIndex(int A[],int m,int B[],int n,int indexs)
	{
		//assume that m<=n is always true
		if (m>n)
		{
			return FindByIndex(B,n,A,m,indexs);
		}
		if (m==0)
		{
			return B[indexs-1];
		}
		if (indexs==1)
		{
			return min(A[0],B[0]);
		}
		int p=indexs/2;
		p=min(p,m);
		if (p<=m)
		{
			if (A[p-1]>B[indexs-p-1])
			{
				return FindByIndex(A,m,B+indexs-p,n-indexs+p,p);
			}
			else if (A[p-1]==B[indexs-p-1])
			{
				return A[p-1];
			}
			else
			{
				return FindByIndex(A+p,m-p,B,n,indexs-p);
			}
		}
	}
};


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值