算法20:两个排序数组merge后的中值

26 篇文章 0 订阅

算法分析:

思路一:遍历计数法
此题可以变为求:有序数组A的长度是m,有序数组B的长度是n,返回A和B合并后的第k个值。

通过遍历两个有序数组,采用计数的方法,当计数到第k个值时,返回数组合并后的第k个值。时间复杂度为O(m+n),空间复杂度为O(1)。

c++代码如下

//aBuffer:有序数组a
//aLen:有序数据a的长度
//bBuufer:有序数组b
//bLen:有序数组b的长度
//k:第k个值
//kValue:返回k位置的值
int GetKthByMerge(int* aBuffer,int aLen,int* bBuffer,int bLen,int k,int& kValue)
{
    if(aBuffer == NULL || bBuffer == NULL)
    {
        return -1;
    }

    if(aLen == 0 || bLen == 0)
    {
        return -1;
    }

    if(k <=0 || k > aLen+bLen)
    {
        return -1;
    }

    //特殊情况
    if(k == 1)
    {
        kValue = aBuffer[0] > bBuffer[0] ? bBuffer[0]:aBuffer[0];
        return kValue;
    }

    if(k == aLen+bLen)
    {
        kValue = aBuffer[aLen-1] > bBuffer[bLen-1] ? aBuffer[aLen-1]:bBuffer[bLen-1];
        return 0;
    }

    int ai = 0;
    int bi = 0;
    while(ai < aLen && bi < bLen && k > 0)
    {
        if(aBuffer[ai] < bBuffer[bi])
        {
            kValue = aBuffer[ai];
            ai++;
        }
        else
        {
            kValue = bBuffer[bi];
            bi++;
        }

        k--;
    }

    if(k > 0 && ai < aLen)
    {
        kValue = aBuffer[ai+k-1];
    }

    if(k > 0 && bi < bLen)
    {
        kValue = bBuffer[bi+k-1];
    }

    return 0;
}

思路二:充分利用排序数组的特性,采用二分递归的方法,时间复杂度是O(m+n)

c++代码如下

//aBuffer: 有序数组a
//bBuffer: 有序数组b
//aStart: a数组起始位置
//aEnd: a数组结束位置
//bStart: b数组起始位置
//bEnd: b数组结束位置
//k:k值
static int FindKValue(int* aBuffer,int* bBuffer,int aStart,int aEnd,int bStart,int bEnd,int k)
{
    int aLen = aEnd - aStart + 1;
    int bLen = bEnd - bStart + 1;

    //递归结束的条件
    if(aLen == 0)
    {
        return bBuffer[bStart + k];
    }

    if(bLen == 0)
    {
        return aBuffer[aStart + k];
    }

    if(k == 0)
    {
        return bBuffer[bStart] > aBuffer[aStart] ? aBuffer[aStart] : bBuffer[bStart];
    }

    if(k == aLen+bLen-1)
    {
        return bBuffer[bEnd] > aBuffer[aEnd] ? bBuffer[bEnd] : aBuffer[aEnd];
    }

    //ka+kb=k+1;
    int ka = (k+1)*aLen/(aLen+bLen);
    int kb = (k+1) - ka;

    ka = ka + aStart;
    kb = kb + bStart;

    //递归
    if(aBuffer[ka] > bBuffer[kb])
    {
        //重新调整k值
        k = k - (kb-bStart);
        //k值不在 bStart~kb之间
        bStart = kb;
        //k值不在ka~aEnd之间
        aEnd = ka;
    }
    else
    {
        //重新调整k值
        k = k - (ka-aStart);
        //k值不在 aStart~ka之间
        aStart = ka;
        //k值不在kb~bEnd之间
        bEnd = kb; 
    }

    return FindKValue(aBuffer,bBuffer,aStart,aEnd,bStart,bEnd,k);
}

此算法只适合算中值,对于任意的K值还有待修正

***未完待续*******

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值