3.Median of Two Sorted Arrays Leetcode
阅读原文时间:2023年07月11日阅读:1
难度系数:5星
/***************************************************************************
题目:有两个排好序的数组,要求其中位数,时间复杂度控制在O(log(m+n))
一般化:求两个排序数组的第K大的元素
直观思路1:PA和PB首先指向这两个子数组,对比比较,A小则PA++,m++,B小则
PB++,m++,直至m==k ======>> 时间复杂度O(m+n)
正解思路:
由于数组是有序的,又是有序的,能否通过二分等思路来可能筛掉一些元素
关键是设计一种方案让其收敛到最终位置
尝试二分: 若Amid<Bmid,cutA前一半,B后一半,
能确定的是A前一半小于A后一半以及B后一半。
       A------------cut---------------
       B------cut--------
那么A的前一半不可能是中位数,筛掉,要是Bmid小呢,只能筛掉B的前一半
这样不稳定
如果以K的一半为标准呢:
A[k/2-1]==B[k/2-1],说明AB的前k/2-1+k/2-1=k-2个元素在topK内
那么 A[k/2-1]便是第K-1和第K大的数(K为偶数)
A[K/2-1]>B[k/2-1] 去除掉A数组前K/2元素(实际最大能去除整个数组元素)
A[K/2-1]<B[k/2-1] 

step1:当A或B是空时,直接返回A[K-1]或者B[k-1]
step2:当K=1,返回min[A[0],B[0]]
step3:当A[K/2-1]==B[k/2-1] 返回A[K/2-1]
************************************************************/


class Solution{
     public:
        double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2){
             int m = nums1.size(),n = nums2.size();
             int total = m+n;
             cout<<total<<endl;
            if(total&0x1)
                return find_k(&nums1[0],m,&nums2[0],n,total/2+1);
            else
            {
                return (find_k(&nums1[0],m,&nums2[0],n,total/2)
                   +find_k(&nums1[0],m,&nums2[0],n,total/2+1))/2.0;
               }
        }
          private:
        static int find_k(int A[],int m,int B[],int n,int k)
        {
            if(m>n)return find_k(B,n,A,m,k);
            if(m==0) return B[k-1];
            if(k==1)return min(A[0],B[0]);
            int ia = min(m,k/2),ib = k-ia;
            if(A[ia-1]<B[ib-1]) return find_k(A+ia,m-ia,B,n,ib);
            else if(A[ia-1]>B[ib-1])
                  return find_k(A,m,B+ib,n-ib,k-ib);
            else return A[ia-1];
        }
};
int main()
{
     int a[]={1,3,5,7,9};
     int b[]={2,4,6};
     Solution S;
     vector<int> B(b,b+3),A(a,a+5);
     cout<<S.findMedianSortedArrays(A,B)<<endl;
     return 0;
}