【数据结构】多数组上中位数/多数组中第 K 大的数(Olog(n))

/*
* 题目描述给定两个有序数组arr1和arr2,两个数组长度都为N,求两个数组中所有数的上中位数。
* 例如:
* arr1 = {1,2,3,4};
* arr2 = {3,4,5,6};
* 一共8个数则上中位数是第4个数,所以返回3。
*
* arr1 = {0,1,2};
* arr2 = {3,4,5};
* 一共6个数则上中位数是第3个数,所以返回2。

* 要求:时间复杂度O(logN)
*/
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

int getUpMedian(vector<int> arr1, vector<int> arr2);

int main()
{
    vector<int> num_vec1, num_vec2;
    num_vec1 = { 0,1,2 };
    num_vec2 = { 3,4,5 };
    int median = getUpMedian(num_vec1, num_vec2);
    cout << "上中位数是:" << median << endl;
    system("pause");
    return 0;
}

int findKth(const vector<int>& arr1, int s1, int e1,
    const vector<int>& arr2, int s2, int e2,
    int kth)
{
    /*
    * 每次将 k 一分为二,比较两个数组中同样位置的值的大小
    * 如果 a[k/2] < b[k/2] 可以证明 a[k/2] 不会是第 k 小的数
    * 所以可以抛弃 a[k/2] 以及之前的数,然后求第 k-k/2 小的数
    */
    // 保证长度比较小的数组在前面
    if ((e1 - s1) > (e2 - s2))
        return findKth(arr2, s2, e2, arr1, s1, e1, kth);
    // 当某一个数组全部被舍弃以后,也就是求另一个数组的第 k 个数
    if (e1 - s1 < 0)
        return arr2[kth - 1];
    // k 为 1 的时候,判断两个数组第一位的大小返回最小值
    if (kth == 1)
        return min(arr1[s1], arr2[s1]);
    // 注意数组不能越界
    int idx1 = min(kth / 2, e1 - s1 + 1);
    int idx2 = kth - idx1;
    // 分情况判断
    if (arr1[s1 + idx1 - 1] < arr2[s2 + idx2 - 1])
        return findKth(arr1, s1 + idx1, e1, arr2, s2, e2, kth - idx1);
    else if (arr1[s1 + idx1 - 1] > arr2[s2 + idx2 - 1])
        return findKth(arr1, s1, e1, arr2, s2 + idx2, e2, kth - idx2);
    else
        return arr1[s1 + idx1 - 1];
}

int getUpMedian(vector<int> arr1, vector<int> arr2)
{
    int lens1 = arr1.size(), lens2 = arr2.size();
    return findKth(arr1, 0, lens1,
        arr2, 0, lens2, lens1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值