寻找两个有序数组的中位数

题目描述

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

示例

示例一:

nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0

示例二:

nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5

题解

中位数的意义:将一个集合划分为两个长度相等的子集,其中一个子集中的元素总是大于另一个子集中的元素。
分别将nums1和nums2划分为两个子集,划分位置定义为i和j,将nums1Left和nums2Left合并称为Left,将nums1Right和nums2Right合并称为right。要确保left中的元素小于right中的元素,即nums1Left[i-1]要小于nums2Right[j],nums2Left[j-1]要小于nums1right[i]。

如果上述条件成立则证明我们找到了目标对象;
起初设定i=nums1.length/2;j=(nums1.length+nums2.length+1)/2-i;(前提假设m小于等于n,因为j不能为负值)

如果nums1Left[i-1]>nums2Right[j],则证明i太大了,应该减小,因为i越小,nums1Left[i-1]就会减小,j会增大,则nums2Right[j]也会增大。
如果nums2Left[j-1]>nums1Right[i],则证明i太小了,应该增大,因为i越大,nums1Right[i]就会增大,j则会减小,nums1Left[j-1]就会减小。

	 double median=0.0;
		 int m=nums1.length,n=nums2.length;
		 if(m>n) {
			 int []temp=nums1;nums1=nums2;nums2=temp;
			 int tmp=m;m=n;n=tmp;
		 }
		 int imin=0,imax=m,halfLen=(m+n+1)/2;
		 while(imin<=imax) {
			 int i=(imin+imax)/2;
			 int j=halfLen-i;
			 if(i>imin&&nums1[i-1]>nums2[j])// i too big
				 imax=i-1;
			 else if(i<imax&&nums2[j-1]>nums1[i])//i too small
				 imin=i+1;
			 else {
				 double maxLeft=0,minRight=0;
				 if(i==0) 
					 maxLeft=nums2[j-1];
				 else if(j==0) 
					 maxLeft=nums1[i-1];
				 else 
					 maxLeft=Math.max(nums1[i-1], nums2[j-1]);
				if((m+n)%2!=0)
					return maxLeft;
				if(i==m)
					minRight=nums2[j];
				else if(j==n)
					minRight=nums1[i];
				else 
					minRight=Math.min(nums1[i], nums2[j]);
				median=(maxLeft+minRight)/2.0;
				return median;
				}
			 }
		 return median;
	 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值