这道题的重点在于时间复杂度 O(log(m+n)),看到这个一般都会想到二分法,因为二分法的时间复杂度是O(log(m+n))
下面是初始的一些想法,如果你想看更好的完整版的算法思路
-
A[k/2] = B[k/2],那么第 k 大的数就是 A[k/2]
-
A[k/2] > B[k/2],那么第 k 大的数肯定在 A[0:k/2+1] 和 B[k/2:] 中,这样就将原来的所有数的总和减少到一半了,再在这个范围里面找第 k/2 大的数即可,这样也达到了二分查找的区别了。
-
A[k/2] < B[k/2],那么第 k 大的数肯定在 B[0:k/2+1]和 A[k/2:] 中,同理在这个范围找第 k/2 大的数就可以了。
class Solution { public: # define INT_MAX 2147483647 double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int m = nums1.size() , n = nums2.size(); int left = (m + n + 1) / 2;//不用分奇偶 int right = (m + n + 2) / 2;//因为偶数是同样的数字 return (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0; } int findKth(vector<int>& nums1 , int i , vector<int>& nums2 , int j , int k)//设置函数找到第k个数 { if( i >= nums1.size()) return nums2[j + k - 1];//nums1为空数组 if( j >= nums2.size()) return nums1[i + k - 1];//nums2为空数组 if(k == 1) return min(nums1[i], nums2[j]); int midVal1 = (i+k/2-1 < nums1.size()) ? nums1[i+k/2-1] : INT_MAX;//INT_MAX的情况之多发生一次,因为剩下的两个数组的元素的个数一定大于K;所以只会发生一次,并且这个数不会大于INT_MAX,因为第K个数不是数组中最大的数。 int midVal2 = (j+k/2-1 < nums2.size()) ? nums2[j+k/2-1] : INT_MAX; if(midVal1 < midVal2) return findKth( nums1 , i+k/2 , nums2 , j , k-k/2); else return findKth(nums1, i, nums2, j + k / 2 , k - k / 2); } };
这是采用了一种递归的思想来做的,只有前三个if会跳出循环。