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)).数组
You may assume nums1 and nums2 cannot be both empty.this
Example 1:code
nums1 = [1, 3] nums2 = [2] The median is 2.0
Example 2:it
nums1 = [1, 2] nums2 = [3, 4] The median is (2 + 3)/2 = 2.5
以下: [3,4,5] , 那么这组数的中位数就是4 [3,4,5,6] , 那么这组数的中位数就是 (4+5)/2 = 4.5
开始没有注意到时间复杂度,但按照O(m+n)解,也花了我很多时间,多是好久没有接触算法的缘故。io
根据上面对中位数的解释,以及对于题目中给出的有序数组nums1[m],nums2[n]。能够想到,最后确定是nums1的一部分在中位数的左边,一部分数在中位数的右边,nums2同理。function
因此我们能够将nums1和nums2,合并后划分红,左右两个数组。class
nums1[0],...,nums1[i-1] | nums1[i] ... nums1[m-1] nums2[0],...,nums2[j-1] | nums2[j] ... nums2[m-1]
也能够当作是下面这种im
nums1[0],...,nums1[i-1],nums2[0],...,nums2[j-1] | nums1[i] ... nums1[m-1],nums2[j] ... nums2[m-1]
左右两个数组的总数多是奇数,也多是偶数。因此规定,若是是奇数,那么左边比右边多一个,若是是偶数,那么左右两边相等。总结
这里来讲一下i和j的关系
左边数组的个数 t =(int)(m+n+1)/2
j = t - i.
理解清楚了i和j的关系以后,那么接下来就要判断中位数了
抓住数组有序这个条件。
可知若是知足中位数的条件左边最大的数leftMax 小于 右边最小的数rightMin
而且左边数组个数必定是等于右边数组个数,或者是比右边数组个数多1个。
最重要的来了
根据上面一系列的条件,那么如今要作的就是经过二分法选出合适的i,进而获得中位数
还得考虑边界问题,这个在下面代码中给出注释
代码以下:
class Solution{ /** * @param Integer[] $nums1 * @param Integer[] $nums2 * @return Float */ function findMedianSortedArrays($nums1, $nums2) { $m = count($nums1); $n = count($nums2); //若是$m>$n时,后面的$j会可能小于0。也就是上面提到的不等式( t =(int)(m+n+1)/2。j = t - i.) if($m>$n) return $this->findMedianSortedArrays($nums2,$nums1); $t = (int)(($m+$n+1)/2); $i = 0; $j = 0; /** 要理解清楚下面两组max,min的意思 */ $leftMax = 0;//左边数组的最大值 $rightMin = 0;//右边数组的最小值 $iMax = $m;//二分法的右边界 $iMin = 0;//二分法的左边界 while($iMax >= $iMin){ //二分法 $i = (int)(($iMax+$iMin)/2); $j = $t-$i; if ($i>0 && $j<$n && $nums1[$i-1] > $nums2[$j]){//利用数组有序,能够只比较一次 $iMax=$i-1; }elseif ($j>0 && $i<$m && $nums1[$i] < $nums2[$j-1]){//利用数组有序,能够只比较一次 $iMin=$i+1; }else{//二分到最后 最佳位置 if ($i==0){ $leftMax = $nums2[$j-1]; }elseif ($j==0){ $leftMax = $nums1[$i-1]; }else { $leftMax = max($nums2[$j-1],$nums1[$i-1]); } if(($m+$n)%2 == 1){//数组和是奇数 return $leftMax; } //数组和是奇数 if ($i == $m){ $rightMin = $nums2[$j]; }elseif ($j == $n){ $rightMin = $nums1[$i]; }else { $rightMin = min($nums2[$j],$nums1[$i]); } return ($leftMax+$rightMin)/2; } } } }
讲解问题的能力还有待进一步提升。若是有问题欢迎私聊。