/*
* 题目描述给定两个有序数组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);
}
【数据结构】多数组上中位数/多数组中第 K 大的数(Olog(n))
最新推荐文章于 2024-08-08 11:47:39 发布