貌似是去年阿里巴巴c++的笔试题,没有什么创新直接照搬的。。。
题意就是找出两个排序数组的中间数,其实就是找出两个排序数组的第k个数。
二分答案,先二分出一个数,再用二分算出这个数在两个排序数组排序第几,然后和k做比较,最后以这个比较为依据接着二分直到求出第k个数。
本来这是两重二分,由于楼主的懒已经没有办法治疗了,用库函数upper_bound()代替了第二重二分,有志者可以自己写第二重二分,楼主就偷懒了。。。
警告:由于题目很神奇,会出现两个排序数组为空的情况,楼主差点因为这个报警。。。。
1 class Solution { 2 public: 3 int findkth(vector<int>& nums1, vector<int>& nums2, int k){ 4 int l = min(nums1[0],nums2[0]); 5 int r = max(nums1[nums1.size() - 1], nums2[nums2.size() - 1]); 6 while(l <= r){ 7 int mid = l + (r - l)/ 2; 8 int k1 = upper_bound(nums1.begin(), nums1.end(), mid) - nums1.begin() ; 9 int k2 = upper_bound(nums2.begin(), nums2.end(), mid) - nums2.begin() ; 10 if(k1 + k2 == k){ 11 if(k1 > 0 && mid == nums1[k1 - 1]) return mid; 12 else if(k2 > 0 && mid == nums1[k2 - 1]) return mid; 13 else r = mid - 1; 14 } 15 else if(k1 + k2 > k){ 16 r = mid - 1; 17 } 18 else l = mid + 1; 19 } 20 return l; 21 } 22 double getmid(vector<int>& nums){ 23 if(nums.size() % 2 == 0) return (nums[nums.size() / 2 - 1] + nums[nums.size() / 2]) / 2.0; 24 else return nums[nums.size() / 2]; 25 } 26 double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { 27 if(nums1.size() == 0 && nums2.size() == 0) return 0.0; 28 if(nums1.size() == 0) return getmid(nums2); 29 if(nums2.size() == 0) return getmid(nums1); 30 int k = (nums1.size() + nums2.size() + 1) / 2; 31 if((nums1.size() + nums2.size()) % 2 == 0){ 32 return (findkth(nums1, nums2, k) + findkth(nums1, nums2, k + 1))/2.0; 33 } 34 else return findkth(nums1, nums2, k); 35 } 36 };