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

 

注意时间复杂度要求。线性时间算法是比较容易的,利用merge的思想即可。即使数组没有排序,也可用partition达到线性时间的选择,但是这里要求O(log (m+n))

 

主要思想:

O(log (m+n))选择两个数组中第k个数,先假设两个数组都足够长,递归操作如下。

1、比较A[k/2-1]B[k/2-1]

如果A[k/2-1]<B[k/2-1],那么[A[0],A[k/2-1]必然都小于第k个数,去除这部分,k=k-k/2

如果A[k/2-1]>B[k/2-1],那么[B[0],B[k/2-1]必然都小于第k个数,去除这部分,k=k-k/2

如果相等,任意进行上述两种操作(其实A[k/2-1]B[k/2-1]就是要选的数,如果A、B长度不足则需要如此操作)

2、如果A,B任意一个为空,取另一个的第k

3、如果k=1,则取min(A[0],B[0])

实际情况下,1中如A,B长度不足,则取最后的那个数的编号代替k/2-1。

 

代码:递归

class Solution {
public:
    double findMedianSortedArrays(int A[], int m, int B[], int n) {
        if((m+n)%2==1)
			return findKth(A,m,B,n,(m+n)/2+1);
		else
			return (findKth(A,m,B,n,(m+n)/2)+findKth(A,m,B,n,(m+n)/2+1))/2.0;
    }

	double findKth(int A[],int m,int B[],int n,int k)
	{
		if(m==0)
			return B[k-1];
		if(n==0)
			return A[k-1];
		if(k==1)
			return min(A[0],B[0]);
		int pa=min(k/2,m);
		int pb=min(k/2,n);
		if(A[pa-1]<=B[pb-1])
			return findKth(A+pa,m-pa,B,n,k-pa);
		else
			return findKth(A,m,B+pb,n-pb,k-pb);
	}
};


 

代码:迭代,实测速度可以快30%(多次提交发现时间是不同的,相差还不小,速度提升没那么多,不过还是快15%左右……)

对于题目取中值的情况,如果返回abegin,bbegin,k,理论上可以再提高50%的速度。

class Solution {
public:
    double findMedianSortedArrays(int A[], int m, int B[], int n) {
        if((m+n)%2==1)
			return findKth(A,m,B,n,(m+n)/2+1);
		else
			return (findKth(A,m,B,n,(m+n)/2)+findKth(A,m,B,n,(m+n)/2+1))/2.0;
    }

	double findKth(int A[],int m,int B[],int n,int k)
	{
		int abegin=0,aend=m,bbegin=0,bend=n;
		int pa,pb;
		while(abegin<aend&&bbegin<bend&&k>1)
		{
			pa=min(abegin+k/2,aend);
			pb=min(bbegin+k/2,bend);
			if(A[pa-1]<=B[pb-1])
			{
				k-=pa-abegin;
				abegin=pa;
			}
			else
			{
				k-=pb-bbegin;
				bbegin=pb;
			}
		}
		if(abegin>=aend)
			return B[bbegin+k-1];
		else if(bbegin>=bend)
			return A[abegin+k-1];
		else
			return min(A[abegin],B[bbegin]);
	}
};


 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值