leetCode-4-Median of Two Sorted Arrays-Hard

descrition

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

解析

注意题目对时间复杂度的要求:O(log (m+n)),在加上数组有序的条件,此处应该联想到二分搜索的优化。那要如何用呢?看下面分析。(也可以参考 leetcode 中的 solution,解释得也很好)

定义函数接口:

double findMedianSortedArrays(vector<int>& A, vector<int>& B)

即两个数组 A, B,假设大小分别为 m 和 n

将数组 A 根据任意位置 i 分成左右两部分,同理 B 根据任意位置 j 也分成左右两部分,如下:

left_part                | right_part
A[0], A[1], ..., A[i-1] | A[i], A[i+1], ... , A[m]
B[0], B[1], ..., B[j-1] | B[j], B[j+1], ... , B[n]

由中位数的定义以及数组有序的条件,我们希望以上划分满足:

len(left_part) = len(right_part)
==> i+j = m-i + n-j (or: i+j = m-i + n-j + 1 (奇数的情况,将多的一个放到左边))
==> j = (m+n+1)/2 - i, i=[0,m]
max(left_part) <= min(right_part) ==> A[i-1] <= B[j] && B[j-1] <= A[i]

由此我们只需要在有序数组 A 上进行二分查找,确定 i 的位置,使得以上条件满足即可找到合适的划分。在此基础上我们可以根据划分边界求得 median。

初始条件:imin = 0, imax = m;
当 imin <= imax 时候的一次迭代:
i = (imin + imax) / 2
j = (m+n+1)/2 - i
// 此处讨论暂时不考虑边界情况,即假设 i 和 j 都合法
// 只可能出现以下几种情况:
(1) A[i-1] <= B[j] && B[j-1] <= A[i]
// 划分满足要求,可以停止循环
(2) A[i-1] > B[j]
// A[i-1] 太大,也就是我们要想办法调整 i 的值使得 A[i-1] <= B[j] 成立
// 这个时候如果我们增大 i,只会使得 A[i-1] 更大 (因为数组是非递减有序的)
// 因此我们只能通过减小 i,尝试找到更小的 A[i-1],因此作出如下调整
imax = i-1
(3) B[j-1] > A[i]
// B[j-1] 太大,同理我们应该减小 j
// 从另一个角度,减小 j 就相当于增大 i,因此我们作出以下调整
imin = i+1

几个细节:

  • m <= n 必须成立。因为 j = (m+n+1)/2 - i,如果 m>n,那么 j 将有可能为负数。因此在程序的开始进行检查。
  • 边界条件的讨论。当 i0, j0, im, jn 时,A[i-1], B[j-1], A[i], B[j] 都是不成立的。如果 i 和 j 都满足要求时,我们需要检查 A[i-1] <= B[j] && B[j-1] <= A[i] 是否成立,那么当 i 和 j 到达边界条件时,我们也就不需要检查其中的某一个条件,比如当 i == 0 时, A 数组的左边为空,我们就不需要检查 A[i-1] <= B[j] 这个条件。(参看代码)

code


#include <iostream>
#include <vector>
#include <algorithm> using namespace std; class Solution{
public:
double findMedianSortedArrays(vector<int>& A, vector<int>& B){
// insure the size of A is less than and equal to the size of B
if(A.size() > B.size())
swap(A, B);
int m = A.size();
int n = B.size();
// m <= n // when m+n is odd, the follow equation will insure the median
// will be assined into left part.
int lenLeft = (m+n+1) / 2; // binary search
int imin = 0, imax = m;
while(imin <= imax){
int i = (imin + imax) / 2;
int j = lenLeft - i;
if( i>0 && A[i-1] > B[j]){
// A[i-1] too large, decreasing i
// i > 0 ==> j<n, because j = (m+n+1) / 2 - i < (m+n+1) / 2 < 2n+1/2 < n
imax = i-1;
}else if ( i<m && B[j-1] > A[i]){
// A[i] too small, increasing i
// i < m ==> j>0, because j = (m+n+1) / 2 - i > (m+n+1) / 2 - m > (2m+1)/2 - m > 0
imin = i+1;
}else{
// perfit
int maxLeft = 0;
if(i == 0){
maxLeft = B[j-1];
}else if (j == 0){
maxLeft = A[i-1];
}else{
maxLeft = max(B[j-1], A[i-1]);
} if( ((n+m)&1) == 1) // odd
return maxLeft; int minRight = 0;
if(i == m){
minRight = B[j];
}else if (j == n){
minRight = A[i];
}else{
minRight = min(B[j], A[i]);
} return (maxLeft + minRight)*1.0 / 2.0;
}
} return 0.0;
}
}; int main()
{
return 0;
}

[array] leetCode-4-Median of Two Sorted Arrays-Hard的更多相关文章

  1. 【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays

    一道非常经典的题目,Median of Two Sorted Arrays.(PS:leetcode 我已经做了 190 道,欢迎围观全部题解 https://github.com/hanzichi/ ...

  2. LeetCode(3) || Median of Two Sorted Arrays

    LeetCode(3) || Median of Two Sorted Arrays 题记 之前做了3题,感觉难度一般,没想到突然来了这道比较难的,星期六花了一天的时间才做完,可见以前基础太差了. 题 ...

  3. LeetCode 4 Median of Two Sorted Arrays (两个数组的mid值)

    题目来源:https://leetcode.com/problems/median-of-two-sorted-arrays/ There are two sorted arrays nums1 an ...

  4. Leetcode 4. Median of Two Sorted Arrays(二分)

    4. Median of Two Sorted Arrays 题目链接:https://leetcode.com/problems/median-of-two-sorted-arrays/ Descr ...

  5. LeetCode 4. Median of Two Sorted Arrays & 归并排序

    Median of Two Sorted Arrays 搜索时间复杂度的时候,看到归并排序比较适合这个题目.中位数直接取即可,所以重点是排序. 再来看看治阶段,我们需要将两个已经有序的子序列合并成一个 ...

  6. 第三周 Leetcode 4. Median of Two Sorted Arrays (HARD)

    4. Median of Two Sorted Arrays 给定两个有序的整数序列.求中位数,要求复杂度为对数级别. 通常的思路,我们二分搜索中位数,对某个序列里的某个数 我们可以在对数时间内通过二 ...

  7. Leetcode 4. Median of Two Sorted Arrays(中位数+二分答案+递归)

    4. Median of Two Sorted Arrays Hard There are two sorted arrays nums1 and nums2 of size m and n resp ...

  8. LeetCode 004 Median of Two Sorted Arrays

    题目描述:Median of Two Sorted Arrays There are two sorted arrays A and B of size m and n respectively. F ...

  9. leetcode 4. Median of Two Sorted Arrays

    https://leetcode.com/problems/median-of-two-sorted-arrays/ There are two sorted arrays nums1 and num ...

  10. leetcode之 median of two sorted arrays

    这是我做的第二个leetcode题目,一开始以为和第一个一样很简单,但是做的过程中才发现这个题目非常难,给人一种“刚上战场就踩上地雷挂掉了”的感觉.后来搜了一下leetcode的难度分布表(leetc ...

随机推荐

  1. apollo实现c#与android消息推送(二)

    安装完成apache apollo后,org.eclipse.paho是很方便的测试软件,下来介绍paho的安装和使用 2. 搭建paho: a 下载 org.eclipse.paho.ui.app- ...

  2. hdu4686 Arc of Dream 2013 Multi-University Training Contest 9矩阵快速幂

    Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Tot ...

  3. hdu3507 Print Article(斜率DP优化)

    Zero has an old printer that doesn't work well sometimes. As it is antique, he still like to use it ...

  4. wireshark数据包分析实战 第二章

    1,监听网络线路:即嗅探器的位置确定. 2,混杂模式:将网卡设置成混杂模式,网卡可以接受经过网卡的所有数据报,包括目的地址不是本网卡的数据报.这些数据都会发送给cpu处理,这样,wireshark就能 ...

  5. 网时|细数被鹿晗热点效应带火的心机boy们

    今天上班早高峰的地铁格外的宽敞,不知道是不是因为大家都被鹿晗关晓彤的甜蜜暴击到已经忘了上班这码事了.本以为是为了新戏<甜蜜暴击>做宣传,结果工作室都相继承认,他们倒是甜蜜了,暴击全给粉丝了 ...

  6. cellForItemAtIndexPath没有调用

    前几天碰到cellForItemAtIndexPath这个数据源方法没有被调用.这是一个collectionView返回cell(item)的数据源方法. 它没有被调用的原因有下: 1.没有设置del ...

  7. cmd获取python返回值

    test.py代码如下: import urllib2 import sys try: f = urllib2.urlopen('http://www.baidu.com/',timeout = 10 ...

  8. Sqlserver数据库 通过表触发器 实时通知应用程序

    /* Sqlserver数据库开始相关服务 以下示例显示了如何查看 OLE Automation Procedures 的当前设置.0未启用 */ EXEC sp_configure 'show ad ...

  9. java8中Stream数据流

    筛选重复的元素 Stream 接口支持 distinct 的方法, 它会返回一个元素(根据流所生成元素的 hashCode和equals方法实现)的流. 例如,以下代码会筛选出列表中所有的偶数,并确保 ...

  10. 如何删除错误提交的 git 大文件

    早上小伙伴告诉我,他无法拉下代码,我没有在意.在我开始写代码的时候,发现我的 C 盘炸了.因为我的磁盘是苏菲只有 256G 放了代码就没空间了,于是我查找到了原来是我的代码占用了居然有 2000+M ...