题目描述:
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
示例:
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
示例 3:
输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
示例 4:
输入:nums1 = [], nums2 = [1]
输出:1.00000
示例 5:
输入:nums1 = [2], nums2 = []
输出:2.00000
要求:时间复杂度为log(m+n)
解析:
不能全排序(nlogn)
也不能靠二分合并(n)
要联想到快排每次循环可以直接确认到一位的准确位置
代码:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class solution
{
public:
//类似找第k大
int find_k(vector<int> arr_1, int i, vector<int> arr_2, int j, int k)
{
//当一边数组被排查空后,第k大为另一数组的开始的顺序第k位
if (i >= arr_1.size())
{
return arr_2[j + k - 1];
}
if (j >= arr_2.size())
{
return arr_1[i + k - 1];
}
//k=1时,此时需要比较两数组的首元素,选出更小的一位
if (k == 1)
{
return min(arr_1[i], arr_2[j]);
}
int mid_arr_1 = (i + k / 2 - 1 < arr_1.size()) ? arr_1[i + k / 2 - 1] : INT_MAX;
int mid_arr_2 = (j + k / 2 - 1 < arr_2.size()) ? arr_2[j + k / 2 - 1] : INT_MAX;
//每次的循环都会排除k/2个元素,两数组中的第k大在下一次循环中成为新两数组的第k-k/2大
if (mid_arr_1 < mid_arr_2)
{
return find_k(arr_1, i + k / 2, arr_2, j, k - k / 2);
}
else
{
return find_k(arr_1, i, arr_2, j + k / 2, k - k / 2);
}
}
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2)
{
int mid_1 = (nums1.size() + nums2.size() + 1) / 2;
int mid_2 = (nums1.size() + nums2.size() + 2) / 2;
return (find_k(nums1, 0, nums2, 0, mid_1) + find_k(nums1, 0, nums2, 0, mid_2)) * 1.0 / 2;
}
};