LeetCode 第四题 Median of Two Sorted Arrays 二人 渣渣选手乱七八糟分析发现基本回到思路1
题目
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)).
You may assume nums1 and nums2 cannot be both empty.
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
一句话题意,用O(log2(n+m))O(log_2(n+m))O(log2(n+m))的时间复杂度找出两个数组中的数的中位数。
思路
思路1——直接合并
求中位数说白了就是要找第k大数。
偶数个k有两个取值,奇数k一个取值。
最简单的做法是直接“合并”数组。但是这种做法——
T=O(n+m)M=O(1)T=O(n+m) \quad M = O(1)T=O(n+m)M=O(1)
所以,必然不能合并。
根据复杂度可以猜测是需要用到二分。
思路2——定位两个数组的中间元素,二分
直接定位两个数组的中间元素x和y(下标为数组长度整除2).
示意图如下——
黑色和橙色分别为输入的两个数组。
蓝色是虚拟的两个数组合并后的数组。
每个数组都分为了左右两个长度大致相当的两部分(偶数时相同,奇数时有部分多一个数)。
方框中的字母代表这一部分的第一个元素。
暂时不细致的考虑边界情况,粗略的叙述。
对于x,如果x落在蓝左,则大致可以淘汰黑左,否则可以淘汰黑右.
对于y,如果y落在橙左,则大致可以淘汰橙左,否则可以淘汰橙右.
如此,规模总的缩小为原来的二分之一。
然而,这就需要解决一个问题——
在橙色数组中比x小的元素有多少个。
解决了这个问题就可以确定x在蓝色中的位置。
这个问题可以使用二分解决,O(log2m)O(log_2m)O(log2m)
如此T(n,m)=O(log2m)+O(log2n)+T(n/2,m/2)T(n,m)=O(log_2m)+O(log_2n)+T(n/2,m/2)T(n,m)=O(log2m)+O(log2n)+T(n/2,m/2)
这个的复杂度我不会算了,但我估计是超过了O(log2(n+m))O(log_2(n+m))O(log2(n+m)).
思路3——利用不等式的传递性
在思路2中,我们是用x,y各自淘汰其所在数组的一半元素。
其实是分了两步,而且这两部其实是各自独立,互不相关的。
要达到O(log2(n+m))O(log_2(n+m))O(log2(n+m))的复杂度,需要我们把问题缩小为原来规模的一半,
但在思路2中我们忽略了不等式的传递性。
为了叙述方便,而且这只是思路,因此下面的不怎么考虑不能除尽、取整的边界问题。
不妨设x<=y(否则可以交换一下两个数组的位置)
因此,可以确定黑左<=x<=y<=蓝右且黑左<=黑右
因此两个数组的右半部分都排在黑左的后面,我们黑左里面的排名的上限被确定了,里面的绝大多数元素可以淘汰(之所以不说全部是因为实际上要考虑边界情况)。因此考虑边界情况时,可以往前移动一下(最多移动1格还是2格)。
同理,橙右可以确定排名的下限,然后……
如此,我们O(1)的做到了问题规模缩小一半,复杂度解决了。
然而,个人感觉边界情况讨论起来有点头皮发麻,估计if语句不好写,代码不好写呀。

思路4——为何要两个数组都恰好各自分成相当的两块呢?
思路3中因为分成两半的情况涉及到奇数偶数的差异,两个组合起来情况有点多,我选择死亡。
但是注意到思路3中是利用不等式的传递性来确定排名上下限,而且淘汰掉的两部分刚好是对角的,那么为何不构造一种划分方法,避免边界情况讨论呢?
符号约定
A分成Al,ArA_l,A_rAl,Ar两部分,长度分别为la,ral_a,r_ala,ra
B分成Bl,BrB_l,B_rBl,Br两部分,长度分别为lb,rbl_b,r_blb,rb
Al,BlA_l,B_lAl,Bl最后一个元素是x1,y1x_1,y_1x1,y1
Ar,BrA_r,B_rAr,Br第一个元素是x2,y2x_2,y_2x2,y2
ala_lal表示数组AlA_lAl中任意一个元素,ar,br,cra_r,b_r,c_rar,br,cr同理。
rank(item)rank(item)rank(item)表示itemitemitem在合并后的有序数组的下标(从0计)。
确定限定条件
Ll=la+lb,Lr=ra+rbL_l=l_a+l_b,L_r=r_a+r_bLl=la+lb,Lr=ra+rb
L=n+m=Ll+LrL=n+m=L_l+L_rL=n+m=Ll+Lr
- 若x2≤2x_2 \leq _2x2≤2
利用不等式的传递性,得:
rank(al)≤rank(x2)−1=L−Lr−1rank(a_l) \leq rank(x_2)-1 = L-L_r-1rank(al)≤rank(x2)−1=L−Lr−1
rank(br)≥rank(y2)≥Llrank(b_r) \geq rank(y_2) \geq L_lrank(br)≥rank(y2)≥Ll
寻找rank为k的元素,欲稳定的可以淘汰Al,BrA_l,B_rAl,Br
,则需要
L−1−Lr<kLl>kL-1-L_r \lt k \\
L_l \gt kL−1−Lr<kLl>k
得Lr>L−1−kLl>kL_r \gt L-1-k \\ L_l>kLr>L−1−kLl>k
另外淘汰数是la+rbl_a+r_bla+rb - 若x2≥y2x_2 \geq y_2x2≥y2
同样有:Lr>L−1−kLl>kL_r \gt L-1-k \\ L_l>kLr>L−1−kLl>k
淘汰数是:lb+ral_b+r_alb+ra
为了稳定的将规模缩小为原来的一半,需要
la+rbl_a+r_bla+rb,lb+ral_b+r_alb+ra各占总规模的一半。
不防令
la+rb=p=L/2lb+ra=L−pl_a+r_b=p=L/2 \\
l_b+r_a=L-pla+rb=p=L/2lb+ra=L−p
上面的公式中出现的除号是整除,不是整除将会使用分号表示,后同
因此,所有约束条件是:
①Lr>L−1−k  ②Ll>k③ra+rb=L/2
① L_r \gt L-1-k \; \\
② L_l>k \quad \quad \quad \quad \\
③ r_a+r_b = L/2 \quad
①Lr>L−1−k②Ll>k③ra+rb=L/2
开始构造
不妨设n<=mn<=mn<=m(否则交换)
取定la∈[0,n]l_a \in [0,n]la∈[0,n],则
rb=L/2−la=(n+m)/2−la∈[0,m].r_b=L/2-l_a=(n+m)/2-l_a \in [0,m].rb=L/2−la=(n+m)/2−la∈[0,m].
故lal_ala确定,lb,ra,rbl_b,r_a,r_blb,ra,rb皆确定,且都是在所在数组长度范围内。
Ll=la+lb=la+m−rb=la+m−(n+m)/2+la=2la+m−(n+m)/2L_l = l_a+l_b=l_a+m-r_b \\ =l_a+m-(n+m)/2+l_a \\ =2l_a+m-(n+m)/2 \quad \quad Ll=la+lb=la+m−rb=la+m−(n+m)/2+la=2la+m−(n+m)/2
代入②式得:
la>k+(n+m)/2−m2l_a \gt \frac{k+(n+m)/2-m}{2}la>2k+(n+m)/2−m
注意k的取值不是任意的,只有(n+m−1)/2(n+m-1)/2(n+m−1)/2与(n+m)/2(n+m)/2(n+m)/2两个取值,总长度相同时这两个取值一样。
- 当总长度L为奇数,la>n−12⇒la>(n−1)/2l_a \gt \frac{n-1}{2} \Rightarrow l_a \gt (n-1)/2la>2n−1⇒la>(n−1)/2
- 当总长度L为偶数,取前一个数为k,la>n−12⇒la>(n−1)/2l_a \gt \frac{n-1}{2} \Rightarrow l_a \gt (n-1)/2la>2n−1⇒la>(n−1)/2
- 当总长度L为偶数,取后一个数为k,la>n2⇒la>n/2l_a \gt \frac{n}{2} \Rightarrow l_a \gt n/2la>2n⇒la>n/2
由于lal_ala取值只能是整数,且是大于号,因此上面不等式的右边可以向下取整,可以直接换成整除号。
同理,对于①式的LrL_rLr,可以得到:
la<k+(n+m)/2−m+12l_a\lt\frac{k+(n+m)/2-m+1}{2}la<2k+(n+m)/2−m+1
4. 当总长度L为奇数,la<n2⇒la<(n+1)/2l_a\lt\frac{n}{2} \Rightarrow l_a \lt (n+1)/2la<2n⇒la<(n+1)/2
5. 当总长度L为偶数,取前一个数为k,la<n2⇒la<(n+1)/2l_a \lt \frac{n}{2} \Rightarrow l_a \lt (n+1)/2la<2n⇒la<(n+1)/2
6. 当总长度L为偶数,取后一个数为k,la<n+12⇒la<(n+2)/2l_a \lt \frac{n+1}{2} \Rightarrow l_a \lt (n+2)/2la<2n+1⇒la<(n+2)/2
由于lal_ala取值只能是整数,且是小于号,因此上面三个式子的右边的数应该向上取整,可以分子加1再整除。
但是,目前很不幸的发现,lal_ala的上界和下界是相邻的两个整数,而且两不等号个都是不带等于的不等号,因此,lal_ala可取的值是空集。
把小于号换成小于于等于,即①式变成小于等于,一路追溯上去,只需要不淘汰x1x_1x1(或y1y_1y1)即可。
那么lal_ala的取值:
la=n/2+1总长度偶数,且k取后一个数l_a=n/2+1 总长度偶数,且k取后一个数la=n/2+1总长度偶数,且k取后一个数
其余情况la=(n+1)/2l_a=(n+1)/2la=(n+1)/2
因排名小于k被淘汰掉的个数为la−1l_a-1la−1,故k−=la−1k-=l_a-1k−=la−1
代码什么的下次再写
我现在发现求出来的结果和原本的直接两个数组两两对半分差别不大,心态有点崩。而且貌似这样子递归之后k就不是原本的总长度的一半了……
emmmm…
先O(n)暴力通过吧,另外膜拜一下discussion里的dalao解法

O(N)源码
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int l1 = nums1.length;
int l2 = nums2.length;
int l = l1 + l2;
int nums[] = new int[l];
int end = l/2+1;
int i,j,k;
i = j = k = 0;
while (i < l1 && j < l2 && k < end) {
if (nums1[i] < nums2[j])
nums[k++] = nums1[i++];
else
nums[k++] = nums2[j++];
}
while (i < l1 && k < end)
nums[k++] = nums1[i++];
while (j < l2 && k < end)
nums[k++] = nums2[j++];
if (l%2 == 0)
return (nums[l/2-1]+nums[l/2])/2.0;
else
return nums[l/2];
}
}
Runtime: 26 ms, faster than 91.16% of Java online submissions for Median of Two Sorted Arrays.
Memory Usage: 49.7 MB, less than 100.00% of Java online submissions for Median of Two Sorted Arrays.
下次有时间在用discuss里面dalao的方法写一次。
LeetCode 第四题 Median of Two Sorted Arrays 二人 渣渣选手乱七八糟分析发现基本回到思路1的更多相关文章
- leetcode 第4题 Median of Two Sorted Arrays
class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<int&g ...
- leetcode第二题--Median of Two Sorted Arrays
Problem:There are two sorted arrays A and B of size m and n respectively. Find the median of the two ...
- 【LeetCode】4、Median of Two Sorted Arrays
题目等级:Hard 题目描述: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find t ...
- 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
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...
- LeetCode 笔记系列一 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 sort ...
- LeetCode 4 Median of Two Sorted Arrays (两个数组的mid值)
题目来源:https://leetcode.com/problems/median-of-two-sorted-arrays/ There are two sorted arrays nums1 an ...
- 【转载】两个排序数组的中位数 / 第K大元素(Median of Two Sorted Arrays)
转自 http://blog.csdn.net/zxzxy1988/article/details/8587244 给定两个已经排序好的数组(可能为空),找到两者所有元素中第k大的元素.另外一种更加具 ...
- 4. Median of Two Sorted Arrays(topK-logk)
4. Median of Two Sorted Arrays 题目 There are two sorted arrays nums1 and nums2 of size m and n respec ...
随机推荐
- python3配置阿里云短信服务
1.申请阿里云短信服务,具体步骤看我的python2-Django配置短信服务 2.安装依赖 aliyun-python-sdk-core-v3 aliyun-python-sdk-dysmsapi= ...
- Windows环境下Nginx配置本地虚拟域名
进入conf文件夹,新建servers文件夹: 将内部的server配置段提取单独放在一个文件里,存到了conf/servers下,以方便配置多个虚拟主机. 并在nginx.conf里http配置段内 ...
- session和cookie的最深刻理解
先说session 对SESSION的争论好象一直没有停止过,不过幺麽能理解SESSION的人应该占90以上.但还是讲讲,别嫌老~ 有一些人赞成用SESSION,有一些人不赞成.但这个问题到底要怎么说 ...
- 【二】、UML基础知识——图图解乾坤
[二].UML基础知识 UML概述 UML是一个通用的可视化建模语言,不同于编程语言,它通过一些标准的图形符号和文字来对系统进行建模.用于对软件进行描述.可视化处理.构建软件系统的文档.是一套总结了以 ...
- 挂号平台首页开发(UI组件部分)
JQ插件模式开发UI组件 JQ插件开发方法: 1.$.extend() 扩展JQ(比较简单,功能略显不足) $.extend({ sayHello:function(){ console.log(&q ...
- 解决Fail to post notification on channel "null"的方法
mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);mNotifyMgr.cancelAll(); St ...
- 从零构建Flink SQL计算平台 - 1平台搭建
一.理想与现实 Apache Flink 是一个分布式流批一体化的开源平台.Flink 的核心是一个提供数据分发.通信以及自动容错的流计算引擎.Flink 在流计算之上构建批处理,并且原生的支持迭代计 ...
- 「数据挖掘入门系列」Python快速入门
Python环境搭建 本次入门系列将使用Python作为开发语言.要使用Python语言,我们先来搭建Python开发平台.我们将基于Python 2.7版本.以及Python的开发发行版本Anaco ...
- centos5,6的GRUB简介
grub:GRand Unified Bootloader grub 0.x:grub legacy(centos5,6) grub 1.x:grub2(centos7) grub legacy(gr ...
- centos5,6 系统启动流程
linux内核特点: 支持模块化:模块文件的名字以.ko(kernel object)结尾 支持内核运行时,动态加载和卸载模块文件. linux内核组成部分: 核心文件:/boot/vmlinuz-V ...