给定两个大小为 m 和 n 的有序数组 nums1
和 nums2
。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1
和 nums2
不会同时为空。
示例 1:
nums1 = [1, 3] nums2 = [2] 则中位数是 2.0
示例 2:
nums1 = [1, 2] nums2 = [3, 4] 则中位数是 (2 + 3)/2 = 2.5
//归并排序
#include <stdlib.h>
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
int target_a,target_b;
//计算中位数目标位置
int size=nums1Size+nums2Size;
target_a=size/2;
target_b=(size%2)?target_a:target_a-1;
int *tmp=(int *)malloc(size*sizeof(int));
int i=0,j=0,k=0;
if(nums1Size&&nums2Size)
{
while(i<nums1Size&&j<nums2Size)
{//合并
if(nums1[i]<=nums2[j])
{
tmp[k++]=nums1[i++];
}
else
{
tmp[k++]=nums2[j++];
}
}
}
while(i<nums1Size)
{//拷贝剩余数据
tmp[k++]=nums1[i++];
}
while(j<nums2Size)
{//拷贝剩余数据
tmp[k++]=nums2[j++];
}
for(int g=0;g<size;++g)
{
printf("%d ",tmp[g]);
}
printf("\n");
printf("tmp[target_a]:%d ,tmp[target_b]:%d\n",tmp[target_a],tmp[target_b]);
double ret=(tmp[target_a]+tmp[target_b])/2.0;
free(tmp);
tmp=NULL;
return ret;
}
//官方题解
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
// 使较小的数组在前
if(nums1Size>nums2Size)
{
int *tmp=nums1;
int tmp_len=nums1Size;
nums1=nums2;
nums2=tmp;
nums1Size=nums2Size;
nums2Size=tmp_len;
}
int size_left=(nums1Size+nums2Size+1)/2;//左侧容器大小
int left_offset=0;
int right_offset=nums1Size;
while(left_offset<=right_offset)
{//左侧容器最大值小于右侧容器最小值
//左侧容器边界 nums1[i-1] nums2[j-1]
//右侧容器边界 nums1[i] nums2[j]
int i=(left_offset+right_offset)/2;
int j=size_left-i;
if(i<right_offset&&nums2[j-1]>nums1[i])
{//nums2较小值大于nums1较大值 需增大i
left_offset=i+1;
}
else if(i>left_offset&&nums1[i-1]>nums2[j])
{//nums1较小值大于nums2较大值 需减小i
right_offset=i-1;
}
else
{//先判断边值条件
int max_left=0;
if(i==0)
{
max_left=nums2[j-1];
}
else if (j==0)
{
max_left=nums1[i-1];
}
else
{
max_left=nums2[j-1]>nums1[i-1]?nums2[j-1]:nums1[i-1];
}
//当总元素个数为奇数时,左边容器最大值为目标中位数
if((nums1Size+nums2Size)%2)
{
return max_left;
}
int max_right=0;
if(i==nums1Size)
{
max_right=nums2[j];
}
else if(j==nums2Size)
{
max_right=nums1[i];
}
else
{
max_right=nums2[j]<nums1[i]?nums2[j]:nums1[i];
}
return (max_right+max_left)/2.0;
}
}
return 0.0;
}
一开始使用的是归并排序的思想,时间复杂度不符合要求
后尝试使用二分法降低时间复杂度,由于对边界认知不够清晰,看了官方题解豁然开朗