赞
踩
4.给定两个大小为 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
----------------------------------------------------------------------------------------------------------------------------------------------------------------
(1)中位数,这个概念您大概得了解一下,按顺序排列的一组数据中居于中间位置的数。
1 4 5,的话中间的数就是4,和平均值没啥关系。 一堆数要是偶数的话就是 中间位置的两个数的值得平均值。
(2)这题吧,一个数组有序想找中位数好找,可以用二分法,what?什么是二分法?想想曾经的一个电视节目,幸运52,
,最短时间猜商品价格,你打算咋猜,从1开始吗?NO,当然猜个你认为最差不多的了,主持人会根据你的答案说大了,小了,之后就按照提示继续猜吧。
(3)两数组和一起,还得有序,要是没有时间复杂度的要求,似乎还可以好处理一下,这个时间复杂度,是这个题的难度直线上升。
不过没事一会与大家交流一下,我们要做的是先能解决一下问题,之后再巧妙的解决这个问题。
先看视频还是先看问题说明,随您【学渣带你刷Leetcode】B站 https://www.bilibili.com/video/BV1C7411y7gB?p=4
(一)不管思想怎么样,考虑一下你的会或者能写点什么。万一这里面的一些想法对做题有帮助呢
(1)合并后的数组的个数为nums1Size+nums2Size;
(2)中位数就应该是这么多数据中的“中间位置"----满足定义的意思啊。
(3)怎么找合并的序列的“中间位置呢”?
3.1先合并成有序序列
逐项比较大小,小的放入结果数组。谁的数据都用完了,就原样放进去吧。
3.2按照奇偶找位置就好了。
(二)结合二分思维,多思考,使劲想,想掉头发掉,没事,掉着掉着就习惯了。
(1)先想几个事
1.1 k=(n+m+1)/2;
i+j=k;
1.2 一共n个位置,可以尝试i;
1.3 若出现A[i-1]<B[j],说明划分大了,需要把往左边移动
若出出现B[j-1]>A[i],说明i划分的有点小,需要往大了调整
这一切的调整都要满足i别取到边
1.4 满足条件时,不同的情况讨论,
i取0,取n不同的时候
普通时候,合并后数组奇偶的情况。
(2)上述的几件事再琢磨一遍。
- #include <stdio.h>
- #include <stdlib.h>
- double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size)
- {
- double result;
- int total=nums1Size+nums2Size;
- int nums_result[total];
- int i=0,j=0,k=0;
-
- while (i<nums1Size&&j<nums2Size)
- {
- if (nums1[i]<nums2[j])
- {
- nums_result[k]=nums1[i];
- i++;
- k++;
- }
- else
- {
- nums_result[k]=nums2[j];
- j++;
- k++;
- }
- }//while
- if(i==nums1Size)
- {
- while (j<nums2Size)
- {
- nums_result[k]=nums2[j];
- k++;
- j++;
- }
- }
- if(j==nums2Size)
- {
- while (i<nums1Size)
- {
- nums_result[k]=nums1[i];
- k++;
- i++;
- }
- }
- int t=0;
- for( t=0; t<nums1Size+nums2Size; t++)
- {
- printf("%d ",nums_result[t]);
- }
- printf("\n");
-
- result= (total%2==0)?((nums_result[total/2-1]+nums_result[total/2])/2.0):nums_result[total/2];
- return result;
- }
-
- double findMedianSortedArrays2(int* nums1, int nums1Size, int* nums2, int nums2Size)
- {
- int n=nums1Size;
- int m=nums2Size;
- if(n>m)
- {
- return findMedianSortedArrays(nums2,nums2Size,nums1,nums1Size);
- }
- int L=0,R=n;
- int i,j;
- int k=(n+m+1)/2;
- while(L<=R)
- {
- i=(L+R)/2;
- j=k-i;
- if(i&&nums1[i-1]>nums2[j])
- {
- R=i-1;
- }
- else if(i!=n&&nums2[j-1]>nums1[i])
- {
- L=i+1;
- }
- else //满足了,找到了最小的划分
- {
- double min;
- if(i==0)
- min=nums2[j-1];
- else if(j==0)
- min=nums1[i-1];
- else
- min=(nums1[i-1]>nums2[j-1])?nums1[i-1]:nums2[j-1];
- //奇数
- if((n+m)%2)
- return min;
-
- double max;
- if(i==n)
- max=nums2[j];
- else if(j==m)
- max=nums1[i];
- else
- max=(nums1[i]<nums2[j])?nums1[i]:nums2[j];
- return (min+max)/2.0;
-
- }
- }
- return 0.0;
-
- }
-
- int main()
- {
- int nums1Size,nums2Size;
- printf("请输入数组1和2的个数\n");
-
- scanf("%d %d",&nums1Size,&nums2Size);
-
- printf("请输入数组1,例(1 2):");
- int nums1[nums1Size];
- int i;
- for(i=0; i<nums1Size; i++)
- {
- scanf("%d",&nums1[i]);
- }
-
- printf("请输入数组2,例(3 4):");
- int nums2[nums2Size];
- int j;
- for(j=0; j<nums2Size; j++)
- {
- scanf("%d",&nums2[j]);
- }
-
- double result=findMedianSortedArrays(nums1, nums1Size, nums2, nums2Size);
- double result2=findMedianSortedArrays2(nums1, nums1Size, nums2, nums2Size);
-
- printf("是不是最少得会写点啥?:%.1lf\n",result);
- printf("是时候表演真正的技术了:%.1lf\n",result2);
-
-
-
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。