问题描述: 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 2 3 4 nums1 = [1, 3] nums2 = [2] The median is 2.0
这道题最直观的解法是(伪代码 描述):
1 2 3 4 5 6 def findMedianSortedArrays (nums1, nums2 ): nums3 = nums1 + nums2 sorted (nums3) if nums3.length is even: return (nums3[nums3.length / 2 ] + nums3[nums3.length / 2 - 1 ]) / 2 return nums3[(nums3.length - 1 ) / 2 ]
即合并排序取中间值。
从伪代码易得,该算法的时间复杂度即排序算法的时间复杂度。没有仔细分析,但应该可以做到平均$O(log(m+n))$。
但合并已排序数组可以通过依次比较nums1和nums2来做,利用已经做好的排序。算法不是很好描述,比较好举例,已题目数据为例
1 2 3 nums1[0 ] < nums2[0 ] so nums3[0 ] = nums1[0 ] nums1[1 ] > nums2[0 ] so nums3[1 ] = nums2[0 ] nums3[0 ] = nums1[1 ]
此外还有两个可以优化的点:
得到的数据不需要完整,需要计算量数组长度和的一半
我们不需要目标数组,所以不需要创建新数组
综上,优化后时间复杂度为:$O(\frac{m+n}{2})$,空间复杂度为:$O(1)$。完整代码(C语言描述):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 double findMedianSortedArrays (int * nums1, int nums1Size, int * nums2, int nums2Size) { int nums3Size = nums1Size + nums2Size; bool isNum3SizeEven = (nums3Size % 2 ) == 0 ; int l1 = 0 ; int l2 = 0 ; int l3 = isNum3SizeEven ? (nums3Size / 2 ) : ((nums3Size - 1 ) / 2 ); int *p1 = nums1; int *p2 = nums1; for (int i = 0 ; i <= l3; i++) { if (*nums1 < *nums2) { if (l1 == nums1Size) { if (i == (l3 - 1 )) { p1 = nums2; } else if (i == l3) { p2 = nums2; } nums2++; l2++; } else { if (i == (l3 - 1 )) { p1 = nums1; } else if (i == l3) { p2 = nums1; } nums1++; l1++; } } else { if (l2 == nums2Size) { if (i == (l3 - 1 )) { p1 = nums1; } else if (i == l3) { p2 = nums1; } nums1++; l1++; } else { if (i == (l3 - 1 )) { p1 = nums2; } else if (i == l3) { p2 = nums2; } nums2++; l2++; } } } return isNum3SizeEven ? (((double )*p1 + (double )*p2) / 2 ) : *p2; }