【LeetCode】4. Median of Two Sorted Arrays (2 solutions)
Median of Two Sorted Arrays
There are two sorted arrays A and B 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)).
解法一:保底做法,O(m+n)复杂度
按照归并排序的思路,先归并,再找中间值。
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m = nums1.size();
int n = nums2.size();
vector<int> array = merge(nums1, nums2);
return ((double)(array[(m+n-)/]+array[(m+n)/]))/;
}
vector<int> merge(vector<int> A, vector<int> B)
{
vector<int> ret;
int m = A.size();
int n = B.size();
int i = ;
int j = ;
while(i < m && j < n)
{
if(A[i] <= B[j])
{
ret.push_back(A[i]);
i ++;
}
else
{
ret.push_back(B[j]);
j ++;
}
}
if(i == m)
{
while(j < n)
{
ret.push_back(B[j]);
j ++;
}
}
if(j == n)
{
while(i < m)
{
ret.push_back(A[i]);
i ++;
}
}
return ret;
}
};

解法二:类似二分查找,复杂度O(log(m+n))
这个解法大概思路很简单,就是A数组的中间元素与B数组的中间元素相比较,从而删掉较小元素所在数组的前一半和较大元素所在数组的后一半。递归下去。
其实要正确实现以上解法还是比较tricky的,因为需要涉及到很多边界情况,我们来一一解释:
第一步,我们需要将题目改为寻找第k小的元素findKthSortedArrays。(这里k从1开始计算)
原因在于,如果我们执着于median,那么在删除一半左右元素形成的子问题中,很难保证仍然是寻找median。可能变为寻找median前一个或者后一个。
(如果仔细思考过这个题就能理解这句话)
改成第k小元素的好处就是,我们可以将删掉的元素考虑进来,在子问题中不断改变k的值。
(例如:本来我们需要寻找的median是第5个数,删掉前面2个数之后,在子问题中就变为寻找第5-2=3个数)
考虑A、B数组总数的奇偶性,就转化为调用findKthSortedArrays的问题了。
第二部:实现findKthSortedArrays
(一)首先,我们规定A数组比B数组短。
这样处理的好处在于:我们所需的(k-1)/2位置可能大于某个数组总长度,规定A短之后,只需要考虑超过A的长度,不需要再复制代码分情况讨论了。
这里需要斟酌一下:为什么不是k/2? k/2±1?而是(k-1)/2
我的思考如下:
如果k==1,2,就是需要比较头两个元素,因此下标为0
如果k==3,4,就是需要比较第1个元素,因此下标为1
综上归纳而得。
(二)其次,把特殊情况处理掉。
(1)A数组为空时,即返回B数组第k个元素。
(2)k==1时,即返回A[0]、B[0]中小的那个
(三)接下来再分为两种情况:
(k-1)/2位置是否超过A数组长度?
(1)若超过,则A数组派出的代表Acandi就是最后元素A[m-1],B派出的代表Bcandi是B[k-m-1]
(a)Acandi==Bcandi,那么正好有k-2个元素比Acandi、Bcandi小,所以第k个元素就是Acandi/Bcandi
(b)Acandi > Bcandi,那么最多只有m-1+k-m-1=k-2个元素比Bcandi小,因此包括Bcandi在内之前的k-m个B数组元素肯定不是第k个数,所以删去,子问题变为寻找第k-(k-m)个元素
(c)Acandi < Bcandi,那么最多只有m-1+k-m-1=k-2个元素比Acandi小,因此包括Acandi在内之前的整个A数组元素m个元素肯定不是第k个数,所以删去,子问题变为寻找第k-m个元素
(2)若不超过,则A数组派出的代表Acandi就是A[(k-1)/2],B派出的代表Bcandi是B[(k-1)/2]
(a)Acandi==Bcandi,那么正好有(k-1)/2+(k-1)/2=k-1个元素比Acandi、Bcandi小,所以第k个元素就是Acandi/Bcandi
如果不相等,对于Acandi 、Bcandi本身是否需要取舍就要注意分析了。
经过举几个例子简单分析就很容易发现,k为奇数时,需要保留小的candidate,舍弃大的。
而k为偶数时,需要保留大的candidate,舍弃小的。
(b)Acandi > Bcandi
(b.1)k为奇数,保留Bcandi,删除Bcandi前面的(k-1)/2个元素,删除A及A后面的元素(保留A中前(k-1)/2个元素)
(b.2)k为偶数,保留Acandi,删除Bcandi及前面的(k-1)/2+1个元素,删除A后面的元素(保留A中前(k-1)/2+1个元素)
(c)Acandi < Bcandi
同(b),略去不赘述了。
class Solution {
public:
double findKthSortedArrays(int A[], int m, int B[], int n, int k)
{//k starts from 1
//make sure A is shorter than B
if(m > n)
return findKthSortedArrays(B, n, A, m, k);
//special case1: A empty
if(m == )
return B[k-];
//special case2: k==1 (m>0 is guaranteed)
if(k == )
return min(A[], B[]);
int Acandi, Bcandi;
if((k-)/ >= m)
{//A[(k-1)/2] out of range
Acandi = A[m-];
Bcandi = B[k-m-];
if(Acandi == Bcandi)
return Acandi;
else if(Acandi > Bcandi)
//for A: no skip
//for B: skip the k-m smaller elements (including Bcandi)
return findKthSortedArrays(A, m, B+k-m, n-(k-m), k-(k-m));
else
//for A: skip the m smaller elements
//for B: skip the k-m larger elements
return findKthSortedArrays(A+m, , B, n-(k-m), k-m);
}
else
{
//1,2->index0; 3,4->index1; ...
Acandi = A[(k-)/];
Bcandi = B[(k-)/];
if(Acandi == Bcandi)
return Acandi;
else if(Acandi > Bcandi)
{
//for A: skip the larger elements
//for B: skip the smaller elements
if(k% == )
//keep the smaller candidate, skip the larger
return findKthSortedArrays(A, (k-)/, B+(k-)/, n-(k-)/, k-(k-)/);
else
//keep the larger candidate, skip the smaller
return findKthSortedArrays(A, (k-)/+, B+(k-)/+, n-((k-)/+), k-((k-)/+));
}
else
{
//for A: skip the smaller elements
//for B: skip the larger elements
if(k% == )
//keep the smaller candidate, skip the larger
return findKthSortedArrays(A+(k-)/, m-(k-)/, B, (k-)/, k-(k-)/);
else
//keep the larger candidate, skip the smaller
return findKthSortedArrays(A+(k-)/+, m-((k-)/+), B, (k-)/+, k-((k-)/+));
}
}
}
double findMedianSortedArrays(int A[], int m, int B[], int n)
{
if((m+n)% == )
{//average of two medians
return (findKthSortedArrays(A, m, B, n, (m+n)/) + findKthSortedArrays(A, m, B, n, (m+n)/+))/;
}
else
{
return findKthSortedArrays(A, m, B, n, (m+n)/+);
}
}
};

【LeetCode】4. Median of Two Sorted Arrays (2 solutions)的更多相关文章
- 【LeetCode】4. Median of Two Sorted Arrays 寻找两个正序数组的中位数
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:数组,中位数,题解,leetcode, 力扣,python ...
- 【leetcode】4. Median of Two Sorted Arrays
题目描述: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of t ...
- 【LeetCode】004. Median of Two Sorted Arrays
题目: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the ...
- 【LeetCode】4.Median of Two Sorted Arrays 两个有序数组中位数
题目: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the ...
- 【LeetCode】4. Median of Two Sorted Arrays(思维)
[题意] 给两个有序数组,寻找两个数组组成后的中位数,要求时间复杂度为O(log(n+m)). [题解] 感觉这道题想法非常妙!! 假定原数组为a,b,数组长度为lena,lenb. 那么中位数一定是 ...
- 【一天一道LeetCode】#4 Median of Two Sorted Arrays
一天一道LeetCode (一)题目 There are two sorted arrays nums1 and nums2 of size m and n respectively. Find th ...
- 【leetcode】1213.Intersection of Three Sorted Arrays
题目如下: Given three integer arrays arr1, arr2 and arr3 sorted in strictly increasing order, return a s ...
- 【LeeetCode】4. 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 ...
- 【medium】4. Median of Two Sorted Arrays 两个有序数组中第k小的数
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...
随机推荐
- window.location属性用法及解决一个window.location.search为什么为空的问题
通常用window.location该属性获取页面 URL 地址: 1.什么是window.location? 比如URL:http://b.a.com:88/index.php?name=kang& ...
- UML图中聚合、组合、关联、依赖、泛化的强弱关系
一.泛化 1.说明 泛化是一种继承关系,如果一个类A的所有属性和操作能被另一个类B所继承,则类B不仅可以包含自己独有的属性,而且可以包含类A的属性和操作.继承是类与类或者类与接口之间最常见的关系. 2 ...
- MFC中onmouseover与onmousemove的区别
onmouseover与onmousemove的区别是:当鼠标移过当前对象时就产生了onmouseover事件,当鼠标在当前对象上移动时就产生了onmousemove事件,只要是在对象上移动而且没有移 ...
- 在使用Vs2013打开Vs2008的解决方案时出现了以下错误:此版本的应用程序不支持其项目类型(.csproj)
在使用Vs2013打开Vs2008的解决方案时出现了以下错误: 无法打开 因为此版本的应用程序不支持其项目类型(.csproj). 在网络上找到解决方案: 命令行或者Vs自带的命令提示符输入:deve ...
- jQuery 图片裁剪插件 Jcrop
Jcrop是一个jQuery图片裁剪插件,它能为你的WEB应用程序快速简单地提供图片裁剪的功能.特点如下: 对所有图片均unobtrusively(无侵入的,保持DOM简洁) 支持宽高比例锁定 支持 ...
- Android 为何比 iOS 卡?【转载】
Android 卡是必须的,当你的手机装了 20 多个 app,那不卡才叫见鬼了呢,我手机微信都打不开,手机直接自动重启啦~哪种东西生来就是完美的呢?即便是台式机,也是越用越慢.换句话,如果没有特别原 ...
- .geodatabase与gdb的相互转换
.geodatabase长得是gdb的全称,确实它们有一定的关系,但也有区别. 简单认识一下 有人也问过我,gdb外表像个文件夹,是怎么实现的.gdb数据库是ESRI特有的数据库,它是一些数据集定义. ...
- mysql 分区说明
当 MySQL的总记录数超过了100万后,性能会大幅下降,可以采用分区方案 分区允许根据指定的规则,跨文件系统分配单个表的多个部分.表的不同部分在不同的位置被存储为单独的表. 1.先看下innodb的 ...
- android中RecyclerView控件实现瀑布流布局
本文是在之前文章的基础上做的修改:android中RecyclerView控件的使用 1.修改列表项news_item.xml: <?xml version="1.0" en ...
- 微信小程序 - 自适应swiper高度(非组件)
微信小程序swiper默认高度375rpx,一旦超过这高度,就滑动不到内容了,我们利用css3可以很简单做到这件事情 原理: 利用css3 横轴滚动属性overflow:scroll,设置死swipe ...