LeetCode-寻找两个正序数组的中位数

        链接:寻找两个正序数组的中位数

题目:给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。

其中:nums1.length == m,nums2.length == n,0 <= m <= 1000,0 <= n <= 1000,1 <= m + n <= 2000,-10^6 <= nums1[i], nums2[i] <= 10^6

首先我们要理清什么是中位数,中位数(Median)又称中值,统计学中的专有名词,是按顺序排列的一组数据中居于中间位置的数,代表一个样本、种群或概率分布中的一个数值,其可将数值集合划分为相等的上下两部分。对于有限的数集,可以通过把所有观察值高低排序后找出正中间的一个作为中位数。如果观察值有偶数个,通常取最中间的两个数值的平均数作为中位数。此时得出两个有效信息:1、顺序排列;2、位于中间的数(奇数个为中间的数,偶数个为最中间的两个数的均值)。

该题目给出两个正序已排列的两个数组,求两个数组的中位数,注意两个数组不同时为空,有且仅有一个为空。那么最简单的方式就是先将两个数组合二为一,然后直接根据下标求得到的数组中位数,那么该方法必然会超时间,不然LeetCode也不会将该题列为困难。

那么就需要转变思路,在不合并的情况下求中位数。

假设nums1=[2,7,10,15,17],nums2=[1,3,5,9,16]。为了不做多余的判断,我们求两个最中间的数。即对于偶数个的数组来说求最中间的两个数即可;对于奇数个的数组来说,求最中间的数和其前一个数。

定义两个int型变量:m1,m2,取两个数组中任意一个不为空的数组的首元素赋值给m1和m2用作初始值。定义两个迭代器:it1=nums1.begin()和it2=nums2.begin()。

在循环开始之间我们需要确定循环的次数,对于奇数个需要遍历(m+n+1)/2(或(m+n)/2+1)次,对于偶数个需要遍历(m+n)/2+1次。那么我们遍历(m+n)/2+1次即可求出中位数(无论奇偶)。

每次循环,m2的值赋值给m1以保证m1小于m2且与m2相邻。比较it1和it2所指对象,选取较小的一个值赋值给m2;如果其中一个迭代器为尾后迭代器(即指向相应容器的end)则直接选取另一个迭代器所指的值赋值给m2,并自增相应的迭代器。注意每次循环仅递增其中一个迭代器,迭代次数必然是小于m+n的,所以不会出现两个迭代器都指向尾后迭代器的情况。

循环结束后,判断m+n的奇偶,奇数在直接返回(double)m2,偶数则返回((double)m1+(double)m2)/2。

代码如下:

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
	int N =nums1.size() + nums2.size();
	int n = N / 2 + 1;
	int m1 = ( nums1.empty() ) ? nums2[0] : nums1[0],m2 =m1 ;
	auto it1 = nums1.begin(),it2 = nums2.begin();
	vector<int>::iterator* it;
	while (n--) {
		it = ( it1 == nums1.end() ) ? &it2
			: ( it2 == nums2.end() ) ? &it1
			: ( *it1 < *it2 ) ? &it1 : &it2;
		m1 = m2;
		m2 = **it;
		++*it;
	}
	return (N % 2) ? (double)m2 : ( (double)m1 + (double)m2 ) / 2;
}

 结果如下:

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值