leetcode之Median of Two Sorted Arrays问题

来源:互联网 发布:程序员接私活平台 编辑:程序博客网 时间:2024/05/21 11:09

问题描述:

There are two sorted arrays nums1 and nums2 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)).

题目示例:

Example 1:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5

问题来源:Median of Two Sorted Arrays (详细地址:https://leetcode.com/problems/median-of-two-sorted-arrays/#/description)

问题一般化:由于本题考虑的仅仅是中位数,扩展开来,我们可以考虑任意一个第k小的数,这样将问题一般化,以便编写大型程序时的模块化处理。

思路:本题的difficulty标记为hard,可想而知还是有一点难度的,个人觉得难点主要是时间复杂度的限制,要求时间复杂度为O(log(m+n))。相反,如果不考虑时间复杂度的话,我们可以考虑一下的方法:

方法一:将两个数组合并,排序好之后,然后直接取下标为k-1的数即可,即为题目要求的第k小的数;

方法二:动用两个指针,一个指向(p1)数组nums1,另外一个(p2)指向数组nums2,比较两个指针当前指向的数值的大小,同时动用一个计数器count,比较之后,谁的数值小谁就               往前移。计数器加一,直到count的值加到k则遍历结束。

上面两种方法其实都不符合题意,最后在下面这篇文章找到了正确答案(Median of Two Arrays)。原文用的是英文解释和表述的,并且给出了相应的证明,本人只负责简单的翻译一下。

假定两个数组中的数组个数均多于k/2个(代码中解释为什么多余k/2个,暂时先往下看吧),咱们分别把两个数组中的第k/2-1个取出来,分别记作A[k/2 - 1]和B[k/2 -1],把他们进行比较,有三个结果(这不是废话吗?)

A[k/2 - 1]  <  B[k/2 - 1]

A[k/2 - 1]  =  B[k/2 - 1]

A[k/2 - 1]  >  B[k/2 - 1]

下面考虑第一种情况,A的第k/2个数(数组下标为k/2 - 1)比B的第k/2个数要小,说明当A和B合并之后,A的下标从0到k/2 - 1之间的数都不可能是第K大的数,显然咱们可以将它们剔除掉,有些人可能立马就想到了,这不就是二分查找的思想吗?我可以说是的,就是这么个意思。大于的情况是一样讨论的;等于的话打就更好了,不就直接就找到了吗?免得那么麻烦。有人可能现在产生疑惑了,奇数个和偶数个需要分开来讨论吗?其实是没必要的,合并之后是奇数个的话咱们直接就取正中间的那个,合并之后如果有偶数个数的话,咱们就将两个数加起来除以2.0不就OK啦。

下面我们来考虑一下递归的边界条件:

1)如果其中有一个数组是空的话,那么就直接返回另外一个数组的下标为[k - 1]的就可以了;

2)如果k = 1,也就是说取的是最小值,我们只需要比较A[0]和B[0],然后取他们之间更小的值就行了呗;

3)如果A[k/2 -  1] = B[k/2 - 1],当然只需要返回其中的一个就行了。

OK,分析到此为止,下面开始动手啦!!!

代码:

按题目要求,数组个数分为偶数个和奇数个的情况:

下面就是具体的查询第k大的数的描述了:

这道题第一次见还是比较新颖的,在这参考了下面的这篇博客,就是我上文提到的那篇文章,在这以表感谢啊(http://blog.csdn.net/zxzxy1988/article/details/8587244)。