若干正序数组,求第几小(大)数、中位数

方法一

合并数组后直接计算

方法二

多指针思路:每个数组设置一指针索引,每次选择最小索引进行移动+1,注意考虑右边界淘汰索引

方法三

二分思想:

#define MIN(a,b,c) ((a)<(b)?(a)<(c)?(a):(c):(b)<(c)?(b):(c))

double fun2(int* a, int* b, int* c, int lenthA, int lenthB, int lenthC)
{
    int n = lenthA + lenthB + lenthC;
    if (n % 2)return fun2_1(a, b, c, lenthA, lenthB, lenthC, n / 2 + 1);
    else return 1.0*(fun2_1(a, b, c, lenthA, lenthB, lenthC, n / 2) + fun2_1(a, b, c, lenthA, lenthB, lenthC, n / 2 + 1)) / 2;
}
double fun2_1(int* a, int* b, int* c, int lenthA, int lenthB, int lenthC, int k)
{
    int n = lenthA + lenthB + lenthC;
    int indexA, indexB, indexC, newIndexA, newIndexB, newIndexC;
    indexA = indexB = indexC = 0;
    while (true)
    {
        if (indexA == lenthA)return fun2_2(b, c, indexB, indexC, lenthB, lenthC, k);
        if (indexB == lenthB)return fun2_2(a, c, indexA, indexC, lenthA, lenthC, k);
        if (indexC == lenthC)return fun2_2(a, b, indexA, indexB, lenthA, lenthB, k);
        if (k == 1)return MIN(a[indexA], b[indexB], c[indexC]);
        if (k == 2)
        {
            int min = MIN(a[indexA], b[indexB], c[indexC]);
            if (min == a[indexA])
            {
                return b[indexB] < c[indexC] ? b[indexB] : c[indexC];
            }
            else if (min == b[indexB])
            {
                return a[indexB] < c[indexC] ? a[indexB] : c[indexC];
            }
            else
            {
                return a[indexB] < b[indexC] ? a[indexB] : b[indexC];
            }
        }

        newIndexA = (indexA + k / 3 >= lenthA ? lenthA : indexA + k / 3)- 1;
        newIndexB = (indexB + k / 3 >= lenthB ? lenthB : indexB + k / 3)- 1;
        newIndexC = (indexC + k / 3 >= lenthC ? lenthC : indexC + k / 3)- 1;

        int min = MIN(a[newIndexA], b[newIndexB], c[newIndexC]);
        if (min == a[newIndexA])
        {
            k -= newIndexA - indexA + 1;
            indexA = newIndexA + 1;
        }
        else if (min == b[newIndexB])
        {
            k -= newIndexB - indexB + 1;
            indexB = newIndexB + 1;
        }
        else
        {
            k -= newIndexC - indexC + 1;
            indexC = newIndexC + 1;
        }
    }
}
double fun2_2(int* a, int* b, int index1, int index2,int lenthA,int lenthB, int k)
{
    int indexA, indexB, newIndexA, newIndexB;
    indexA = index1;
    indexB = index2;
    while (true)
    {
        if (indexA == lenthA) return a[indexA + k - 1];
        if (indexB == lenthB) return b[indexB + k - 1];
        if (k == 1)return a[indexA] < b[indexB] ? a[indexA] : b[indexB];

        newIndexA = (indexA + k / 2 >= lenthA ? lenthA : indexA + k / 2) - 1;
        newIndexB = (indexB + k / 2 >= lenthB ? lenthB : indexB + k / 2) - 1;

        if (a[newIndexA] < b[newIndexB])
        {
            k -= newIndexA - indexA + 1;
            indexA = newIndexA + 1;
        }
        else
        {
            k -= newIndexB - indexB + 1;
            indexB = newIndexB + 1;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值