leetcode-Median of Two Sorted Arrays

22 篇文章 0 订阅
1 篇文章 0 订阅

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


求两个已排序数组的中位数问题,数组长度分别为m,n,时间复杂度要求O(log(m+n))

中位数定义:对一个已排序数组a,设长度为l,若l为奇数,中位数为a[l/2],即中间的那个数;若l为偶数,中位数为(a[l/2-1]+a[l/2])/2,即中间的两数的平均值

解法见另一篇转载:http://blog.csdn.net/maverick1990/article/details/21406739


几个需要注意的细节:

1、注意处理m或n长度为0的情况

2、设a当前遍历区间为[al,ar],那么中点为am = (al+ar)/2,设要找第pos位置的数(pos=(m+n)/2),那么把A[am]放到数组B中的对应位置ainb=pos-am,即数组A中A[am]前面有am个数,那么如果A[am]是中位数,在数组B中要有ainb=pos-am个数小于A[am],A[am]要放在B[ainb-1]和B[ainb]两数之间。此时要注意:

(1)ainb是否合法,即满足0<=ainb且ainb-1<n,保证ainb-1,ainb有一个在B数组内。

若ainb<0,证明A[am]前面的am个数已经大于(m+n)/2了,直接将更新ar为am-1;ainb-1>=n的情况以此类推

(2)更新坐标时,要置为ar=am-1或al=am+1,注意边界,防止死循环,并且最后判断new_al是否大于new_ar,若大于,都重新置为原来的al。原因如下:

分析ar-al=1和0的两种边界情况,ar-al=1时,am=al,更新后的情况为,new_al = al, new_ar = al-1 或 new_al = ar, new_ar = ar,对于前一种情况,将new_al和new_ar都置为al为合理;ar=al时,更新后的情况为,new_al = al, new_ar = al-1 或 new_al = ar+1, new_ar = ar,对于这两种情况,将new_al和new_ar都置为al为合理


本题考察重点就是这些细节,我在这上面费了不少时间,面试时候一次写对还是不太容易的。


代码:

#include<iostream>
#include<vector>
#include<map>
#include<string>
#include<cstring>
using namespace std;

class Solution {
private:
	int pm,pn;
public:
	int findPos(int A[],int al,int ar,int B[],int bl,int br,int pos)
	{
		int am = (al+ar)/2;
        int bm = (bl+br)/2;
        
        int ainb = pos-am;
        int bina = pos-bm;
        int nal=al,nar=ar,nbl=bl,nbr=br;
        
        if(ainb<0)
        	nar = am-1;
        else if(ainb-1>=pn)
        	nal = am+1;
        else if(ainb<pn && A[am]>B[ainb])
        	nar = am-1;
        else if(ainb>0 && A[am]<B[ainb-1])
        	nal = am+1;
        else 
			return A[am];
        
        if(bina<0)
        	nbr = bm-1;
        else if(bina-1>=pm)
        	nbl = bm+1;
        else if(bina<=ar && B[bm]>A[bina])
        	nbr = bm-1;
        else if(bina>0 && B[bm]<A[bina-1])
        	nbl = bm+1;
        else 
			return B[bm];
		
		if(nal>nar) nal=nar=al;
		if(nbl>nbr) nbl=nbr=bl;
		return findPos(A,nal,nar,B,nbl,nbr,pos);
	} 
	
    double findMedianSortedArrays(int A[], int m, int B[], int n) 
	{
		//printf("%d %d\n",m,n);
		//printf("%d %d %d %d\n",A[0],A[m-1],B[0],B[n-1]);
		pm = m;
		pn = n;
		double ans;
		if(m==0)
		{
			ans = B[n/2];
			if(n%2==0) ans = (B[n/2-1]+ans)/2.0;
		}
		else if(n==0)
		{
			ans = A[m/2];
			if(m%2==0) ans = (A[m/2-1]+ans)/2.0;
		}
		else
		{
			int al = 0;
	        int ar = m-1;
	        int bl = 0;
	        int br = n-1;
	        
	        int mid = (m+n)/2;
	        ans = findPos(A,al,ar,B,bl,br,mid);
	        if((m+n)%2==0)
	        	ans = (findPos(A,al,ar,B,bl,br,mid-1)+ans)/2.0;
		}
        return ans;
    }
};

int main()
{
	Solution t;
	int a[] = {1,2,3,4,5};
	int b[] = {2,4,7};
	cout<<t.findMedianSortedArrays(a,sizeof(a)/sizeof(int),b,sizeof(b)/sizeof(int))<<endl;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值