题目

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the midian 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.

Example1:

  nums1 = [1, 3]

  nums2 = [2]

  The median is 2.0

Example2:

  nums1 = [1, 2]

  nums2 = [3, 4]

  The median is (2+3)/2.0 = 2.5

思路


二分查找、递归法

假设两个数组A和B中的个数都大于\(\frac{k}{2}\)个(存在某一数组个数不足\(\frac{k}{2}\)个),分别取出第\(\frac{k}{2}\)个元素(数组下标为$\frac{k}{2}-$1)进行比较,此时有三种情况:

  • A[$\frac{k}{2}-$1] \(\;\)< \(\;\) B[$\frac{k}{2}-$1]
  • A[$\frac{k}{2}-$1] \(\;\)=\(\;\) B[$\frac{k}{2}-$1]
  • A[$\frac{k}{2}-$1] \(\;\)>\(\;\) B[$\frac{k}{2}-$1]

对于第一种情况,如果A的第 \(\frac{k}{2}\) 个元素(数组下标为 $ \frac{k}{2}-1$ )比B的第 \(\frac{k}{2}\) 个元素(数组下标为 \(\frac{k}{2}-1\) )小,说明当A和B合并之后,A的下标从0到( \(\frac{k}{2}-1\) )之间的数都不可能是第k大的数,即对数组cut的小了,应该增大k。如果相等,就是需要寻找的元素(第k-1个元素)。大于的情况与小于类似。奇数个就取中间的,偶数个将两个数加起来除以2.0即可。

递归的边界条件:

1)其中某一数组为空的话,则直接返回另一个数组下标为[k-1]的数。(见单数组寻找第k个元素)

2)如果k=1,即查找最小值,直接比较两个数组的第1个元素(数组下标为0)即可。

3)如果A[$\frac{k}{2}-\(1]=B[\)\frac{k}{2}-$1],只需要返回其中的一个。

Tips


Cut思想寻找第k个数

通过Cut,将数组切割为左右两部分:\(Left_{part}, Right_{part}\),此时产生两个元素,分别是左边的最大值\(L_{max}\)和右边的最小值\(R_{min}\)。Cut过程中,可以Cut一个数,则这个数既属于左边,又属于右边;也可以在两个数中间Cut。

  • 单数组寻找第k个元素

    对于有序数组A,在第k个数(数组下标为k-1)cut一下,返回值\(A[k-1]=L{max}\),即为第k个数,该数为左边部分最大值。(k=1,2,...)

  • 双数组寻找第k个元素

\(left_{part}\) \(C_i\) $right_{part} $
\(a_1,a_2,\cdots,a_i\) / \(a_{i+1},a_{i+2},\cdots,a_m\)
\(b_1,b_2,\cdots,b_j\) / \(b_{j+1},b_{j+2},\cdots,a_n\)

定义\(L_{max_1}\),\(L_{max_2}\)为Cut之后\(Left_part\)第1个和第2个数组的最大值,\(R_{min_1}\),\(R_{min_2}\)为Cut之后\(Right_{part}\)第1个和第2个数组的最小值。\(C_1、C_2\)是第1、2个数组的Cut。

如果满足:

1)\(L_{max_1}\;< \;R{min_1}\),\(L_{max_2} \; <\; R_{min_2}\)。(这是一定满足的,因为数组有序,左边一定小于右边。)

2)\(L_{max_1}\;<=\;R_{min_2}\),且\(L_{max_2}\;<=\;R_{min_1}\)。

则\(Left_{part}\)全小于\(Right_{part}\)。如果左边的元素个数加起来刚好等于k,那么第k个元素就是\(Max(L_{max_1},L_{max_2})\)(参见单数组寻找第k个元素)。如果\(L_{max_1}\;>\;R_{min_2}\),说明数组1的左边元素太多(大)了,需要减小\(C_1\),把\(C_2\)增大。同理可得\(L_{max_2}\;>\;R_{min_1}\),将\(C_1\)增大,\(C_2\)减小。

C++

class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int n1 = nums1.size();
int n2 = nums2.size();
int total = n1 + n2; if(total % 2){ //如果数组加起来是奇数
return findKth(nums1, 0, nums2, 0, total / 2 + 1);
}
else{ //如果是偶数
return (findKth(nums1, 0, nums2, 0, total / 2 ) + findKth(nums1, 0, nums2, 0, total / 2 + 1) )/2.0;
} } //分割的思想寻找第k个数
double findKth(vector<int>& nums1, int l, vector<int>& nums2, int r, int k){ int n1 = nums1.size();
int n2 = nums2.size(); if(n1 - l > n2 -r )
return findKth(nums2, r, nums1, l, k); //始终保证第一个数组是个数是最少的 if(n1-l == 0)
return nums2[r + k -1];
if(k == 1)
return min(nums1[l], nums2[r]); int p1 = min(k/2 , n1); //保证在第一个数组内做二分查找。
int p2 = k - p1; if(nums1[l + p1 -1] < nums2[r + p2 -1]){ //左边
return findKth(nums1, l+p1,nums2, r,k - p1);
}
else if(nums1[l + p1 -1] > nums2[r + p2 -1]){ //左边数组1的个数太大
return findKth(nums1, l,nums2, r+p2,k - p2);
}
else{
return nums1[l+p1-1];
}
}
};

python

class Solution(object):
def findKth(self, nums1, nums2,k): k = int(k)
n1 = len(nums1)
n2 = len(nums2) if n1 > n2:
return self.findKth(nums2, nums1, k)
if n1 == 0:
return nums2[k - 1]
if k == 1:
return min(nums1[0], nums2[0])
p1 = int(min(k / 2, n1))
p2 = k - p1
if nums1[p1 - 1] <= nums2[p2 - 1]:
return self.findKth(nums1[p1:], nums2, p2)
else:
return self.findKth(nums1, nums2[p2:], p1) def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
n1 = len(nums1)
n2 = len(nums2)
total = n1 + n2
if(total % 2):
return self.findKth(nums1, nums2, total /2 + 1)
else:
return (self.findKth(nums1, nums2, total /2 )+ self.findKth(nums1, nums2, total /2 + 1))/2.0

参考

[1] https://blog.csdn.net/hk2291976/article/details/51107778

[2] https://leetcode.com/problems/median-of-two-sorted-arrays/solution/

4. Median of Two Sorted Arrays[H]两个有序数组的中位数的更多相关文章

  1. 60.Median of Two Sorted Arrays(两个排序数组的中位数)

    Level:   Hard 题目描述: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find t ...

  2. 《LeetBook》leetcode题解(4): Median of Two Sorted Arrays[H]——两个有序数组中值问题

    我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...

  3. LeetCode:4_Median of Two Sorted Arrays | 求两个排序数组的中位数 | Hard

    题目: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the ...

  4. LeetCode第[4]题(Java):Median of Two Sorted Arrays (俩已排序数组求中位数)——HARD

    题目难度:hard There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median ...

  5. [LeetCode] 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 ...

  6. [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 ...

  7. 力扣 -- 寻找两个有序数组的中位数 Median of Two Sorted Arrays python实现

    题目描述: 中文: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums ...

  8. 《LeetCode-0004》 寻找两个有序数组的中位数-Median of Two Sorted Arrays

    题目给定两个大小为 m 和 n 的有序数组nums1和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 nums2 ...

  9. #leetcode刷题之路4-寻找两个有序数组的中位数

    给定两个大小为 m 和 n 的有序数组 nums1 和 nums2.请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)).你可以假设 nums1 和 nums2 不会 ...

随机推荐

  1. 装饰模式(Decorator)C++实现

    装饰模式 层层包装,增强功能.这就是装饰模式的要旨!装饰器模式就是基于对象组合的方式,可以很灵活的给对象添加所需要的功能.它把需要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象. 意图: 动 ...

  2. Codeforces Round #453

    Visiting a Friend Solution Coloring a Tree 自顶向下 Solution Hashing Trees 连续2层节点数都超过1时能异构 Solution GCD ...

  3. [原创]Eclipse 安卓开发几个异常的处理办法

    一.代码没有问题,就是报错,重启一下就会好.可以先clean再build; 二.R.Java丢失 网上讲了若干方法,有用android toos的,有clean再build的,我的解决办法是勾选bui ...

  4. MFC知识点总结

    一:消息1.什么是消息?消息是驱动windows系统运行的基础.从计算机的角度来看,消息就是一个整数.    (1)一个无符号整数,是消息值:    (2)消息附带的WPARAM和LPARAM类型的参 ...

  5. UBuntu安裝使用PIP

    Windows下安裝python包還是比較方便的,直接在FLD網站下載對應的EXE文件就可以安裝,在linux系統下,使用pip,easy egg 管理工具可以減輕安裝負擔. 原文鏈接:http:// ...

  6. 模拟试题A

    模拟试题A 一.单项选择题(2′*12=24′) 1.下面各种坐标变换中,会产生变换前后维度的改变的是( ) A)建模变换 B)观察变换 C)投影变换 D)视口变换 2.下列描述深度缓冲消隐算法的特点 ...

  7. Kafka学习笔记(7)----Kafka使用Cosumer接收消息

    1. 什么是KafkaConsumer? 应用程序使用KafkaConsul'le 「向Kafka 订阅主题,并从订阅的主题上接收消息.Kafka的消息读取不同于从其他消息系统读取数据,它涉及了一些独 ...

  8. 企业级任务调度框架Quartz(5) Quartz的声明式配置

    前序:     前面我们已经通过编程的方式实现了多个作业任务执行具体操作的演示:但具体到实际的时候,如果我们要在 Job 启动之后改变它的执行时间和频度,则必须去修改源代码重新编译,我们很难去以编程的 ...

  9. 对服务器磁盘、CPU、内存使用状态,设置163邮件告警

    1,桥接模式可上网,首先你的邮箱已经开通yum -y install mailx dos2unix.x86_64  mailx -V[root@localhost ~]# vim /etc/mail. ...

  10. Linux学习二:基于CentOS 6.5的网络配置

    查看网卡信息: ifconfig [root@hadoop01 ~]# ifconfig [正常的显示信息] eth0 Link encap:Ethernet HWaddr :0C::::5C ine ...