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

网上的很多关于此题的做法都有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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值