有兩個排序的數組,長度都爲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;
}