寻找2个排序数组的中位数
也就是求第K大的数字
分割法:
k1=k2=K/2-1,即都分成一半(这里的k1 k2用于下标,故和数量相关的话要加1)
若分割下标比数组数量大,则取分割下标取数组最后一位
若nums1[k1]<nums2[k2]
那么数组1的前k1个可以舍去,接着求第K-k1-1大的数字
同理
若相等,看一下k1+k2+2是否刚好等于Kth,若相等,那么肯定就是这个数字
否则都剔除掉,继续求
int getKth(int l1,int l2,int Kth,vector<int> nums1, vector<int> nums2)
{
int k,k1,k2;
printf("l1=%d,l2=%d,Kth=%d\n",l1,l2,Kth);
if(l1>=nums1.size()) //若nums1被剔除光了,则直接返回nums2的中位数
return nums2[l2+Kth-1];
if(l2>=nums2.size()) //若nums2被剔除光了,则直接返回nums1的中位数
return nums1[l1+Kth-1];
if(Kth==1) //若要找第一大的数字,返回最小的那个即可
return nums1[l1]<nums2[l2]?nums1[l1]:nums2[l2];
k1=k2=Kth/2-1; //找两个分割点k1,k2,刚开始默认为Kth/2-1
//k1和k2用于分割点下标,即[l1+k1],故不是第几大的意思
if(k1>=nums1.size()) //若下标k1大于等于数组总数,则下标置为最大下标
k1=nums1.size()-1;
if(k2>=nums2.size()) //同理
k2=nums2.size()-1;
if(nums1[l1+k1]<nums2[l2+k2]) //剔除1数组前k1个
return getKth(l1+k1+1,l2,Kth-k1-1,nums1,nums2);
else if(nums1[l1+k1]>nums2[l2+k2]) //剔除2数组前k2个
return getKth(l1,l2+k2+1,Kth-k2-1,nums1,nums2);
else
{
if(k1+1+k2+1==Kth) //下标总和加2才是数量总数。若数量综述等于Kth,说明这2个相等的就是要找的
return nums1[l1+k1];
else return getKth(l1+k1+1,l2+k2+1,Kth-k1-k2-2,nums1,nums2); //否则就都剔除,然后找后面的
}
}
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2)
{
int n1,n2,k1,k2;
double num1,num2;
n1=nums1.size();
n2=nums2.size();
if((n1+n2)%2==1)
{
k1=(n1+n2)/2+1;
num1=getKth(0,0,k1,nums1,nums2);
return num1;
}
else
{
k1=(n1+n2)/2;
num1=getKth(0,0,k1,nums1,nums2);
k2=(n1+n2)/2+1;
num2=getKth(0,0,k2,nums1,nums2);
return (num1+num2)/2;
}
}