Median_of_two_sorted_arrays

1.问题描述

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

2.问题分析

这是一类问题,更通用的形式是,给定两个已排序的数组,找到两个所有元素中第k大的元素。可以使用一个计数器,两个指针,类似于merge_sort的原理,移动两个指针,找到第k大的数。但是这种方法空间复杂度O(1),时间复杂度O(m+n),不符合要求。
可以从k入手,上述的方法相当于我们一次删除一个肯定在第k大元素之前的元素,那么我们需要进行k次。但是我们是否可以每次都删除一半呢?由于A和B都是有序的,我们可以充分利用这个信息,类似于二分查找的方式。

一、假设A和B的元素个数都大于k/2个,我们将A[k/2-1]和B[k/2-1]进行比较,有三种情况:
1、A[k/2-1]==B[k/2-1] 说明找到了第k大的元素(k个数恰好一半在A中,一半在B中),直接返回A[k/2-1]或B[k/2-1]
2、A[k/2-1]<B[k/2-1] 说明前k个元素中,会有多于k/2个在A中,少于k/2个在B中,即第k大的元素必不会在A[0]到A[k/2-1]中,可以放心删除。
3、A[k/2-1]>B[k/2-1] 同理,可以删除B[0]到B[k/2-1]
二、假设A和B的元素个数有一个不大于k/2,则对A[m]和B[k-m]进行上述的比较
三、递归的终止条件:
1、当A或者B为空时,直接返回B[k-1]或者A[k-1]
2、当k=1时,返回min(A[0], B[0])
3、当A[k/2-1]==B[k/2-1]时, 返回A[k/2-1]或者B[k/2-1]

3.代码

class Solution
{
public:
	double findMedianSortedArrays(int A[], int m, int B[], int n)
	{
		int total = m + n;
		if(total & 0x1)//如果total为奇数,恰好存在“中间数”
			return find_kth(A,m,B,n,total/2+1);
		else//如果tatal为偶数,则取中间两个数的平均值
			return (find_kth(A,m,B,n,total/2)+find_kth(A,m,B,n,total/2+1))/2.0;
	}

private:
	static int find_kth(int A[],int m,int B[],int n,int k)
	{
		if(m > n)return find_kth(B,n,A,m,k);//将数组A、B中长度较短的调整到第一个参数,便于后续处理
		if(m==0) return B[k-1];				//当第一个数组长度为0时,直接返回B数组第k个元素
		if(k==1) return min(A[0], B[0]);	//当k等于1时,直接返回A,B第一个元素中较小的一个

		//将k分为两部分,一部分是k/2和m中较小的一个,另一部分是k中剩余量
		int ia = min(k/2,m), ib = k-ia;
		if(A[ia-1]<B[ib-1])		//此时,A[0]~A[ia-1]均可被删除,k去掉ia个,递归
			return find_kth(A+ia,m-ia,B,n,k-ia);
		else if(A[ia-1]>B[ib-1])//此时,B[0]~B[ib-1]均可被删除,k去掉ib个,递归
			return find_kth(A,m,B+ib,n-ib,k-ib);
		else 					//此时,两者相等,返回其中一个即可
			return A[ia-1];		
	}
};

4.总结

本题的关键在于利用每次删除k/2的方式,快速找到第k大的元素。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值