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. 51nod 1536不一样的猜数游戏 思路:O(n)素数筛选法。同Codeforces 576A Vasya and Petya's Game。

    废话不多说,先上题目. 51nod Codeforces 两个其实是一个意思,看51nod题目就讲的很清楚了,题意不再赘述. 直接讲我的分析过程:刚开始拿到手有点蒙蔽,看起来很难,然后......然后 ...

  2. hdu1116有向图判断欧拉通路判断

    Play on Words Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

  3. Centos7 创建本地 docker 仓库极其遇到的问题

    环境安装: VirtualBox 安装 Centos7 安装 docker 1. 配置私有仓库和客户端地址 私有仓库:192.168.1.104 客户端:192.168.1.103 通过 Centos ...

  4. 【技巧】datagrid锁定列后重新加载时出现错位问题的解决

    [问题描述]:有时候datagrid设置了锁定列后,在重新加载datagrid数据时,出现锁定列与非锁定列数据错位的问题,如图: [问题分析]:查看css样式我们发现,锁定的列和非锁定的列属于两个不同 ...

  5. python之decode、encode及codecs模块

    一.先说说编解码问题 编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码. Eg: str ...

  6. 关于TileBrush中Viewbox,Viewport以及Stretch,AlignmentX/Y的详细研究

    我们知道TileBrush是WPF中一个战斗力爆表的虚基类,从它派生出的DrawingBrush,ImageBrush和VisualBrush在WPF图形编程中发挥着重要作用.然而关于TileBrus ...

  7. 从源码看 angular/material2 中 dialog模块 的实现

    本文将探讨material2中popup弹窗即其Dialog模块的实现. 使用方法 引入弹窗模块 自己准备作为模板的弹窗内容组件 在需要使用的组件内注入 MatDialog 服务 调用 open 方法 ...

  8. Java 多态、内部类、异常、包

    一.多态 1. 概述 理解:多态可以理解为事物存在的多种体(表)现形态. 例如: 动物中的猫和狗. 猫这个对象对应的是猫类型,例如:猫 x = new 猫(); 同时猫也是动物中的一种,也可以把猫称为 ...

  9. LINUX下分区命令Parted详解

    通常划分分区工具我们用的比较多是fdisk命令,但是现在由于磁盘越来越廉价,而且磁盘空间越来越大.而fdisk工具他对分区是有大小限制的,它只能划分小于2T的磁盘.现在的磁盘空间已经远远大于2T,有两 ...

  10. springcloud干货之服务消费者(ribbon)

    本章介绍springcloud中的服务消费者 springcloud服务调用方式有两种实现方式: 1,restTemplate+ribbon, 2,feign 本来想一篇讲完,发现篇幅有点长,所以本章 ...