首先,根据题目中复杂度为O(log(m+n)),应该是用二分法。刚开始觉得很有想法,应该用分治,就是写不出来,无奈又走上了搜题解的不归路(题解也看了好久好久啊)
怎么用这个二分法呢
两个数组nums1和nums2,不同时为空。i为数组nums1的起始位置,j为数组nums2的起始位置,k表示查找两个数组的第k个元素。运算中一步步缩小要查找元素的范围,用递归来实现,跳出递归的途径有两个:
1、若i>nums1的长度,说明nums1中的所有数字都被淘汰,此时要找的第k个数就是数组nums2的第k个数;j>nums2同理
2、若k=1,则返回两个有序数组起始元素的最小值,即min(nums[1],nums[2])
递归过程:
两个数组长度分别为m和n,总长度为m+n,中位数是第(m+n+1)/2 个数和第 (m+n+2)/2 个数的平均值(奇偶都是如此),所以求中位数的问题就转化为了找第(m+n+1)/2和第(m+n+2)/2个数的问题,即上面所说第k个数
这里,二分的并不是数组,而是k。分别在nums1和nums2中找第k/2个数,若nums1[k/2-1]<nums2[k/2-1],即可淘汰nums1的前k/2个数,同时k要减去k/2。
例如
nums1=[1,2,3],nums2=[2,4,5],要找这两个有序数组的第4个元素,则找到
nums1[k/2-1]=nums1[1]=2,
nums2[k/2-1]=nums2[1]=4,
2<4,则nums1数组第2个元素及其左边的元素均小于nums2的第2个元素,将nums1前两个元素淘汰。同时原先要找的第4个元素,已经变成要找第4-2,即淘汰nums1前两个元素以后的所有元素中的第2个。
继续进行此操作
直到跳出递归结构
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m=nums1.size(),n=nums2.size();
int i=0,j=0;
return (findK(nums1,i,nums2,j,(m+n+1)/2)+findK(nums1,i,nums2,j,(m+n+2)/2))/2.0;
}
int findK(vector<int>& nums1,int i,vector<int>& nums2,int j,int k){
if (i>=nums1.size()){
return nums2[j+k-1];
}
else if(j>=nums2.size()){
return nums1[i+k-1];
}
if(k==1){
return min(nums1[i],nums2[j]);
}
int Vk1=(i+k/2-1<nums1.size())?nums1[i+k/2-1]:INT_MAX;
int Vk2=(j+k/2-1<nums2.size())?nums2[j+k/2-1]:INT_MAX;
if (Vk1<Vk2){
return findK(nums1,i+k/2,nums2,j,k-k/2); //淘汰nums1的前k/2个元素
}
else{
return findK(nums1,i,nums2,j+k/2,k-k/2);
}
}
};
k=k/2和k=k-k/2是不一样的………………粗心了