有两个排序的数组,长度都为n,求合并后的排序数组的中位数。要求时间复杂度为log(n)。
解法1:直接的解法是遍历两个数组并计数,类似归并排序里面的有序数组的合并,复杂度为O(n)
解法2:分治策略:
设两个数组为A[n],B[n]。
若A[n/2] < B[n/2]:中位数k必定位于A[n/2]-A[n]、B[0]-B[n/2]。且k也是两个数组A[n/2]-A[n]、B[0]-B[n/2]的中位数。
若A[n/2] > B[n/2]:中位数k必定位于A[0]-A[n/2]、B[n/2]-B[n]。且k也是两个数组A[0]-A[n/2]、B[n/2]-B[n]的中位数。
若A[n/2] == B[n/2],则A[n/2]为中位数。
若数组无法细分下去,则可直接计算中位数。
设A[i],B[j]为中位数k,则i+j = n;
若A[n/2] < B[n/2]:则 (i-n/2)+j = n/2;
k还是两个数组A[n/2]-A[n]、B[0]-B[n/2]的中位数。
时间复杂度:
#include <stdio.h>
#include <vector>
#include <numeric>
#include <algorithm>
#include <iostream>
using namespace std;
#define debug_
double find_mid_core(vector<int>& nums1, vector<int>& nums2, int left_1, int right_1, int left_2, int right_2)
{
if (right_1 == left_1+1)
{
return (double)(max(nums1[left_1], nums2[left_2]) + min(nums1[right_1], nums2[right_2]))/2.0;
}
int mid_1 = left_1 + ((right_1 - left_1) >> 1);
int mid_2 = left_2 + ((right_2 - left_2) >> 1);
if (nums1[mid_1] > nums2[mid_2])
{
return find_mid_core(nums1, nums2, left_1, mid_1, mid_2, right_2);
}
else if (nums1[mid_1] < nums2[mid_2])
{
return find_mid_core(nums1, nums2, mid_1, right_1, left_2, mid_2);
}
else
{
return nums1[mid_1];
}
}
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2)
{
int left_1 = 0;
int right_1 = nums1.size() - 1;
int left_2 = 0;
int right_2 = nums2.size() - 1;
return find_mid_core(nums1, nums2, left_1, right_1, left_2, right_2);
}
int main()
{
vector<int> vec_1{ 1, 12, 15, 26, 38 };
vector<int> vec_2{ 2, 13, 17, 30, 45 };
cout<<findMedianSortedArrays(vec_1, vec_2);
return 0;
}