题目:
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.
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
题意:
求两个有序数组的中位数。
思路:
如果没有时间复杂度的限制这是一道水题,可惜没有如果。如果两个数组长度和为奇数,输出最中间的那个数;偶数的话就输出最中间两个数的平均值。一脸懵逼,只能去看大佬的解题报告了。将问题转化成求第k小值的问题就可以了。小技巧:假设两个数组长度之和 m+n,查找(m+n+1) / 2、(m+n+2) / 2这两个数的平均值,对于n+m的和为奇数或偶数都适用。
由于时间复杂度O(log (m+n))的要求,故利用二分思想做题(对K二分):设数列A元素个数为n,数列B元素个数为m,各自升序排序,求第k小元素 。分别在nums1和nums2中查找第K/2个元素,注意这里由于两个数组的长度不定,所以有可能某个数组没有第K/2个数字,所以我们需要先判断一下,数组中到底存不存在第K/2个数字,如果存在就取出来,否则就赋值为整型最大值。如果某个数组没有第K/2个数字,那么我们就淘汰另一个数字的前K/2个数字即可。重点:比较这两个数组的第K/2小的数字key1和key2的大小,如果第一个数组的第K/2个数字小的话,那么说明我们要找的数字肯定不在nums1中的前K/2个数字,所以我们可以将其淘汰,将nums1的起始位置向后移动K/2个,并且此时的K也自减去K/2,调用递归。反之,我们淘汰nums2中的前K/2个数字,并将nums2的起始位置向后移动K/2个,并且此时的K也自减去K/2,调用递归即可
Code:
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n=nums1.size(),m=nums2.size(),l=(n+m+1)/2,r=(n+m+2)/2;
return (findk(nums1,0,nums2,0,l)+findk(nums1,0,nums2,0,r))/2.0;
}
int findk(vector<int>& nums1,int l,vector<int>& nums2,int r,int k){
if(l>=nums1.size()) return nums2[r+k-1];
if(r>=nums2.size()) return nums1[l+k-1];
if(k==1) return min(nums1[l],nums2[r]);
int key1=l+k/2-1<nums1.size()?nums1[l+k/2-1]:INT_MAX;
int key2=r+k/2-1<nums2.size()?nums2[r+k/2-1]:INT_MAX;
if(key1<key2) return findk(nums1,l+k/2,nums2,r,k-k/2);
return findk(nums1,l,nums2,r+k/2,k-k/2);
}
};