算法分析与设计丨第三周丨LeetCode(5)——Median of Two Sorted Arrays(Hard)

来源:互联网 发布:骷髅法术升级数据 编辑:程序博客网 时间:2024/06/07 14:19

分治法

题目链接:https://leetcode.com/problems/median-of-two-sorted-arrays/description/

本来上个星期就想做这一题的,试一下hard的难度,想了半天,还是只想出一种朴素的方法:用两个标记分别指向两个vector的begin,这样一个个比较下去,直到数到中位数为止。

也可以类似这道题目一样:http://blog.csdn.net/xxhi008/article/details/77967221,将两个vector合起来再去找中值。

但前面做法的时间复杂度应该是O(m+n),不是题目所要的log(m+n),于是便看了一下discussion,觉得以下这种做法比较优美简洁,反复研究了几天,将思考与大家分享一下。


vector是有nums1,nums2,大小分别为size1,size2。

大体思路是这样的:先假设size1与size2都大于k/2,那么找出nums1[k/2-1]与nums2[k/2-1]比较他们的大小。

如果nums1[k/2-1] < nums2[k/2-1],就说明nums1[k/2-1]前面的nums1[0]到nums1[k/2-1]都比要找的中值要小,即是可以省去的。

同理 nums1[k/2-1] > nums2[k/2-1]也一样处理。

当 nums1[k/2-1] == nums2[k/2-1]时,就说明这两个值就是我们要找的第k大的数,因为前面已经有k-2个数。


 几点注意的地方:

1.我们始终保持nums1为较少数目的vector,这样易于处理。

2.当size1 < k/2时,就取出nums1[size1-1]来处理。

3.我们做的省去的操作的时间复杂度十分低,符合题目要求。

//在做《算法概论》的时候发现,2.22给出了相应的证明,把大神的证明贴在这里


4.递归终止条件1:当size1 == 1时,说明第一个vector全省去了,取nums2[k-1]即为所求

5.递归终止条件2:当k == 1时,说明只要找第1小的数,所以取nums1[0]与nums2[0]的最小值即可。



class Solution {public:    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {        int size1 = nums1.size(),size2 = nums2.size();        if((size1 + size2) % 2 != 0)            return find(nums1,size1,nums2,size2,(size1+size2)/2 + 1);        else            return (find(nums1,size1,nums2,size2,(size1+size2)/2) + find(nums1,size1,nums2,size2,(size1+size2)/2 + 1)) / 2 ;                        }                         double find(vector<int> nums1,int size1,vector<int> nums2,int size2,int k)     {        if(size1 > size2)//保持第一个数组始终较小数目,便于处理            return find(nums2,size2,nums1,size1,k);        if(size1 == 0)//递归终止条件1:数目较少的数组全部舍弃完,只剩下一个数组            return nums2[k-1];        if(k == 1)//递归终止条件2:k==1,即求两个数组中最小值            return min(nums1[0],nums2[0]);                 int temp1 = min(k/2,size1),temp2 = k - temp1;                if(nums1[temp1-1] > nums2[temp2-1])            return find(nums1,size1,vector<int>(nums2.begin() + temp2,nums2.end()),size2 - temp2,k-temp2);        else if(nums1[temp1-1] < nums2[temp2-1])            return find(vector<int>(nums1.begin() + temp1,nums1.end()),size1 - temp1,nums2,size2,k-temp1);        else// if(nums1[temp1] == nums2[temp2])            return nums1[temp1-1];       }                                                };


阅读全文
0 0
原创粉丝点击