求两个不等长的有序数组的中位数

来源:互联网 发布:一淘和淘宝联盟返利高 编辑:程序博客网 时间:2024/05/07 14:04

网上的很多关于此题的做法都有Bug,故想了一下午,终于想到一个自我感觉Bug比较少的解法(可能还有Bug,欢迎大家指正)。

/**   求两个有序数组合并后的中位数,时间复杂度O(logn)*/#include <iostream>#include <string>using namespace std;/**1 2 3 4 5 6 7 8,此时left=right=5,表示如果一个数的右边有至少right个数,那么该数及左边都不是中位数对于奇数的话,统一起见*/void getMid(int *arr1, int n1, int *arr2, int n2){    int left = (n1+n2+1)/2+1;    int right = left;    int begin1 = 1;    int begin2 = 1;    int end1 = n1;    int end2 = n2;    bool flag = false;    while(left!=2 || right!=2)    {        if(begin1>end1 || begin2>end2)          //奇数时,中位数就一个,此时会出现这种情况        {            flag = true;            break;        }        int mid1 = (begin1+end1)/2;        int mid2 = (begin2+end2)/2;        int loffset = 0;        int roffset = 0;        if(arr1[mid1] == arr2[mid2])        {            cout<<arr1[mid1]<<endl;        }        else if(arr1[mid1] < arr2[mid2])        {            if(mid1-begin1+mid2-begin2+2 >= left)            {                roffset = end2 - mid2;                if(roffset == 0 && right!=2)                {                    if(arr2[end2] > arr1[end1])                    {                        end2--;                    }                    else                    {                        end1--;                    }                    right--;                    continue;                }            }            else            {                if(end2-mid2 > 1)                {                    roffset = 1;                }            }            if(end1-mid1+end2-mid2+2 >= right)            {                loffset = mid1 - begin1;                if(loffset == 0 && left!=2)                {                    if(arr1[begin1] < arr2[begin2])                    {                        begin1++;                    }                    else                    {                        begin2++;                    }                    left--;                    continue;                }            }            else            {                if(mid1-begin1 > 1)                {                    loffset = 1;                }            }            begin1 += loffset;            end2 -= roffset;            left -= loffset;            right -= roffset;        }        else        {            if(end1-mid1+end2-mid2+2 >= right)            {                loffset = mid2 - begin2;                if(loffset == 0 && left!=2)                {                    if(arr1[begin1] < arr2[begin2])                    {                        begin1++;                    }                    else                    {                        begin2++;                    }                    left--;                    continue;                }            }            else            {                if(mid2-begin2 > 1)                {                    loffset = 1;                }            }            if(mid1-begin1+mid2-begin2+2 >= left)            {                roffset = end1 - mid1;                if(roffset == 0 && right!=2)                {                    if(arr2[end2] > arr1[end1])                    {                        end2--;                    }                    else                    {                        end1--;                    }                    right--;                    continue;                }            }            else            {                if(end1-mid1 > 1)                {                    roffset = 1;                }            }            begin2 += loffset;            end1 -= roffset;            left -= loffset;            right -= roffset;        }    }    if(flag)    {        if(begin1>end1)        {            for(int i=begin2+left-2; i<=end2-right+2; i++)            {                cout<<arr2[i]<<endl;            }        }        else        {            for(int i=begin1+left-2; i<=end1-right+2; i++)            {                cout<<arr1[i]<<endl;            }        }        return;    }    for(int i=begin1; i<=end1; i++)    {        cout<<arr1[i]<<endl;    }    for(int i=begin2; i<=end2; i++)    {        cout<<arr2[i]<<endl;    }}int main(int argc,char* argv[]){    int arr1[]={0,1,3,6,8};    int arr2[]={0,2,4,5,7};    getMid(arr1, 4, arr2, 4);    return 0;}