LeetCode4. Median of Two Sorted Arrays(寻找第k小数:分治O(log(n+m)))
来源:互联网 发布:papi酱变音软件 编辑:程序博客网 时间:2024/04/29 09:12
题目链接:https://leetcode.com/problems/median-of-two-sorted-arrays/
There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
Example 1:
nums1 = [1, 3]nums2 = [2]The median is 2.0
Example 2:
nums1 = [1, 2]nums2 = [3, 4]The median is (2 + 3)/2 = 2.5
解题思路1:
求两个有序数组的中位数,首先O(n+m)的算法很好想,二路归并的思想作一个新的数组,对数组寻秩访问,代码如下,LeetCode也能AC
class Solution {public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { vector<int>v; int median = nums1.size() + nums2.size(); int i,j; for(i = 0,j = 0;i < nums1.size()&&j<nums2.size();){ //二路归并 if(nums1[i] < nums2[j]){ v.push_back(nums1[i]); ++i; } else{ v.push_back(nums2[j]); ++j; } } if(i == nums1.size()){ while(j < nums2.size()) {v.push_back(nums2[j]); ++ j;} } else if(j == nums2.size()){ while(i < nums1.size()) {v.push_back(nums1[i]); ++ i;} } if(median&1){ return v[(median-1)/2] + 0.0; } return (v[median/2]+v[median/2-1])/2.0; }};
但是题目要求的O(log(n+m))的算法,只能分而治之解决。
解题思路2:
当m+n为偶数时,median = 第(m+n)/2个值 和 第(m+n)/2+1个值 的平均值;
当m+n为奇数时,median = 第(m+n)/2 + 1个值;
所以,我们可以把问题抽象成:O(log(n+m))的时间内,从两个有序数组A[ ] 、B[ ] 找到合并后的第k小值;
为了解决这个问题,首先,我们要证明一个最关键的命题. 或者说,为什么可以用k/2去分治?
假定,我们取A[ ]中第k/2小值,即A[k/2 - 1]这个元素(另pa = k/2),对应取B[ ]的第pb小值(令pb = k - pa);
{
换句话说,我们从A[ ]、B[ ]两数组中取k个比较小的数,但是,这k个数并不一定包含合并后的第k小值,而是通过舍弃一些逐渐逼近;
}
那么,A[pa-1]和B[pb-1]存在以下三种关系:
1_____________
A[pa-1] == B[pb-1] : 说明第k小值一定在这k个数中间,而且必定等于A[pa-1]且等于B[pb-1];
2__________
A[pa-1] < B[pb-1] : 结论是A[0..pa-1]一定不是第k小值,他们一定都比第k小值要小;从A[pa]往后去找;
{
证明:反证法 \
A[0] A[1] ... A[pa-1]..... (pa = k/2)
B[0] B[1] ... ......................B[pb-1]....... (pb = k - pa = k - k/2)
当A[pa-1] < B[pb-1],我们说A[0..pa-1]<= A[pa-1] < 第k小值
不妨设A[pa-1]是第k+1小值,B[pb-1]是第k+2小值,那么:
A[ ]数组中比A[pa-1]小至多有k/2-1个,不包括自己;
B[ ]数组中比A[pa-1]小至多有k - k/2 - 1个,不包括B[pb-1]因为B[pb-1] > A[pa-1];
那么,比A[pa - 1]小的至多有(k/2-1) + (k - k/2 - 1) = k - 2个,这与A[pa-1]是第k+1小值矛盾!前者充其量只能说明: A[pa-1]是第k-1小值,是这个意思吧?!!!!
所以,说A[0..pa-1]一定不是第k小值,他们一定都比第k小值要小,把他们舍弃即可;
}
3________
A[pa-1] > B[pb-1] : 同理,结论是B[0..pb-1]一定不是第k小值,他们一定都比第k小值要小;从B[pb]往后去找;
综上所述,用k/2去分而治之,递归解决,注意递归基(边界条件):
1.若A[ ] 或 B[ ]为空,即只有一个数组,那么返回B[k-1] 或 A[k-1];
2.若k == 1,即合并后的最小值,那么返回A[0]和B[0]中的较小者即为全局最小值;
为了减少代码以实现边界条件1,可以维护保持第一个数组元素数量少于第二个(m < n),方法是交换,这样只需判断m == 0?即可; A[ ]中没有k/2那么多元素的话,取到末尾m;
参考代码:
double find(int a[],int m,int b[],int n,int k){//第k小值 if(m > n) return find(b,n,a,m,k); //保证第一个数组是短的 if(!m) return b[k-1]; //a[]为空,返回b[]中第k个位置 if(k == 1) return min(a[0],b[0]); //第1小值,是a[0]和b[0]中的较小者 int pa = min(k/2,m),pb = k - pa; // 用k/2去分解 if(a[pa-1] < b[pb-1]) return find(a+pa,m-pa,b,n,k-pa); //a[0..pa-1]肯定都在第k个位置的左边 else if(a[pa-1] > b[pb-1]) return find(a,m,b+pb,n-pb,k-pb);//b[0..pb-1]肯定也在第k个位置的左边 else return a[pa-1]; //第k个位置的值 == a[pa-1] == b[pb-1]}class Solution {public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int m = nums1.size(); int n = nums2.size(); int sum = m+n; int *a = &nums1[0],*b = &nums2[0]; // vector => a[] if(sum&1){ return find(a,m,b,n,(sum + 1)/2); //问题抽象为查找两顺序数组的第k小值 } else{ return (find(a,m,b,n,sum/2) + find(a,m,b,n,sum/2 + 1))/2.0; } }};
- LeetCode4. Median of Two Sorted Arrays(寻找第k小数:分治O(log(n+m)))
- Median of Two Sorted Arrays O(log (m+n))
- LeetCode, Median of Two Sorted Arrays, Java Solution, O(m+n), O(log(m+n))
- LeetCode4. Median of Two Sorted Arrays分治法
- LeetCode - 4. Median of Two Sorted Arrays : 逆推法 O(log(min(m,n))))
- leetcode 4. Median of Two Sorted Arrays O(log(m+n))解法
- [LeetCode4]Median of Two Sorted Arrays
- leetcode4 Median of two sorted arrays
- leetcode4 Median of Two Sorted Arrays
- LeetCode4:Median of Two Sorted Arrays
- leetcode4:Median of Two Sorted Arrays
- leetcode4~Median of Two Sorted Arrays
- leetcode4. Median of Two Sorted Arrays
- LeetCode4—Median of Two Sorted Arrays
- leetcode4. Median of Two Sorted Arrays
- LeetCode4. Median of Two Sorted Arrays
- leetcode4 Median of Two Sorted Arrays
- Leetcode4. Median of Two Sorted Arrays
- secureCRT安装步骤
- 魔法阵题解
- Android开源 -- 开源的基于 Material Design设计的豆瓣的Android客户端“豆芽”
- Spring+SpringMVC+MyBatis+MySql框架整合实例
- 如何测试你的系统是大端还是小端模式
- LeetCode4. Median of Two Sorted Arrays(寻找第k小数:分治O(log(n+m)))
- el表达式截取字段
- 苏嵌21 16.11.25补充内容 指针数组 数组指针 函数指针 指针函数数组
- 2017学习计划--待定
- c语言程序
- STM32 使用printf打印串口信息
- 关于textarea的相关实践
- contentprovider的学习实例
- Java IO读写操作