这个问题的大意是提供两个有序的整数数组A与B,A与B并集的中间数。[1,3]与[2]的中间数为2,因为2能将A与B交集均分。而[1,3]与[2,4]的中间数为2.5,取2与3的平均值。故偶数数目的中间值与奇数数目的中间值的算法不同。这个问题要求时间复杂度不超过O(log(n+m)),其中n与m分别为A与B的长度。


对于这个问题,我一开始的想法是同时对两个集合用二分查找法,这样每次过程都能有效减少一部分的冗余数据,且这样的算法的时间复杂度为O(log(n)+log(m))=O(log(max(n,m))=O(log(n+m))。

但是在这个问题的解答区看到了一个更优的解决方案。

https://discuss.leetcode.com/topic/4996/share-my-o-log-min-m-n-solution-with-explanation

其优化的方案是明确了一个有用的想法。我们可以找到一个切割点i与j,将A与B做如下切分:

A[0], ..., A[i-1] | A[i], ..., A[n - 1],

B[0], ..., B[j-1] | B[j], ..., B[m - 1]

如果i'与j'能够满足下面条件,那么就能将A与B的并均分为A[0], ..., A[i'-1], B[0], ..., B[j'-1]与A[i'], ..., A[n - 1], B[j'], ..., B[m - 1],且前者中所有元素都不大于后者的任意元素。

1.i'+j' = n-i'+m-j' -> 2i+2j'=n + m (保证两个集合拥有等量数值)

2.not (i'-1>=0 and j'<m and A[i'-1]>B[j]) (保证A[0], ..., A[i'-1]中所有元素都小于B[j'], ..., B[m - 1])

3.not (j'-1>=0 and i'<n and B[j'-1]>A[i]) (保证B[0], ..., B[j'-1]中所有元素都小于A[i'], ..., A[n - 1])

上面需要对i'与j'的范围做校验是因为可能存在空集(比如当i=0时,{A[0],..., A[i-1]}表示一个空集),空集应该满足所有的比较关系,因为它不包含任何元素,我们自然可以对其所有元素做任意假定。

由条件1可以看出,可能符合条件的j可以由i唯一确定。不妨设n<m(不然可以在开始时交换二者引用),那么利用二分查找法可以保证只做log(n)次循环就可以得到正确的i与j,而每次循环只需要花费常量时间,故这样一个算法的复杂度就称为了O(log(A.length))=O(log(min(n,m))。

这里可以使用二分查找法的原因是,若存在i,j满足条件1,但是不满足条件2(或条件3),那么正确的切割i’<i(或i'>i),这是因为当i增大时,j就会相对减小,而若i'>i,会致使A[i'-1]>=A[i-1]>B[j]>=B[j'],故条件2依旧不成立,因此正确的切割i’<i(或i'>i)。

lb = 0, rb = n

while lb <= rb then

  i = (lb + rb) / 2

  j = (n + m) / 2 - i //条件1

  if i - 1 >= 0 and j < m and A[i-1] > B[j] then //条件2

    rb = i

  else if j-1 >= 0 and i < n and B[j-1] > A[i] then //条件3

    lb = i + 1

  else

    i' = i, j' = j

    break

一但我们得到了i'与j',那么就可以轻易的计算中间数,中间数应该是(max(A[0], ..., A[i'-1], B[0], ..., B[j'-1])+min(A[i'], ..., A[n - 1], B[j'], ..., B[m - 1])) / 2,这条式子等价与(max(A[i'-1], B[j'-1])+min(A[i'], B[j'])) / 2。

上面只给出了当n+m为偶数时的解决方案,而对于n+m为奇数时可以将j = (n + m) / 2 - i替换为j = (n + m + 1) / 2 - i,即将中间值保存在A[0], ..., A[i'-1], B[0], ..., B[j'-1]中。最后的结果应该为max(A[i'-1], B[j'-1])。


最后给出java代码,有需要的人可以看看

package cn.dalt.leetcode;

/** * Created by dalt on 2017/6/4. */public class MedianOfTwoSortedArrays2 {    public static void main(String[] args) {        int[] nums1 = new int[]{1};        int[] nums2 = new int[]{2, 3, 4};        System.out.println(new MedianOfTwoSortedArrays2().findMedianSortedArrays(nums1, nums2));    }

    public double findMedianSortedArrays(int[] nums1, int[] nums2) {        if (nums1.length > nums2.length) {            int[] temp = nums1;            nums1 = nums2;            nums2 = temp;        }

        int len1 = nums1.length;        int len2 = nums2.length;        int totalLength = len1 + len2;        int halfLength = totalLength >> 1;        int offset = totalLength & 1;        int lbound = 0;        int rbound = nums1.length;        while (lbound <= rbound) {            int i = (lbound + rbound) >> 1;            int j = ((len1 + len2 + offset) >> 1) - i;            if (j < len2 && i > 0 && nums1[i - 1] > nums2[j]) {                rbound = i;            } else if (j > 0 && i < len1 && nums2[j - 1] > nums1[i]) {                lbound = i + 1;            } else {                int smallmid = i <= 0 ? nums2[j - 1] : j <= 0 ? nums1[i - 1] : Math.max(nums1[i - 1], nums2[j - 1]);                if (offset == 0) {                    int largermid = i >= len1 ? nums2[j] : j >= len2 ? nums1[i] : Math.min(nums1[i], nums2[j]);                    return (smallmid + largermid) / 2.0;                }                return smallmid;            }        }        return -1;    }}

leetcode:Median of Two Sorted Arrays分析和实现的更多相关文章

  1. LeetCode: Median of Two Sorted Arrays 解题报告

    Median of Two Sorted Arrays There are two sorted arrays A and B of size m and n respectively. Find t ...

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

  3. [leetcode]Median of Two Sorted Arrays @ Python

    原题地址:https://oj.leetcode.com/problems/median-of-two-sorted-arrays/ 题意:There are two sorted arrays A ...

  4. 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 sorted ...

  5. LeetCode—— Median of Two Sorted Arrays

    Description: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the medi ...

  6. Leetcode: Median of Two Sorted Arrays. java.

    There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted ...

  7. C++ Leetcode Median of Two Sorted Arrays

    坚持每天刷一道题的小可爱还没有疯,依旧很可爱! 题目:There are two sorted arrays nums1 and nums2 of size m and n respectively. ...

  8. LeetCode——Median of Two Sorted Arrays

    Question There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median o ...

  9. LeetCode Median of Two Sorted Arrays 找中位数(技巧)

    题意: 给两个有序(升or降)的数组,求两个数组合并之后的中位数. 思路: 按照找第k大的思想,很巧妙.将问题的规模降低,对于每个子问题,k的规模至少减半. 考虑其中一个子问题,在两个有序数组中找第k ...

随机推荐

  1. 《深入理解java虚拟机》学习笔记之虚拟机即时编译详解

    郑重声明:本片博客是学习<深入理解java虚拟机>一书所记录的笔记,内容基本为书中知识. Java程序最初是通过解释器(Interpreter)进行解释执行的,当虚拟机发现某个方法或代码块 ...

  2. [置顶] 【Android实战】----从Retrofit源码分析到Java网络编程以及HTTP权威指南想到的

    一.简介 接上一篇[Android实战]----基于Retrofit实现多图片/文件.图文上传中曾说非常想搞明白为什么Retrofit那么屌.最近也看了一些其源码分析的文章以及亲自查看了源码,发现其对 ...

  3. mysql 视图,触发器,存储

    一.视图 概念:其实就是一个临时表. 视图是一个虚拟表(非真实存在的),其本质是[根据SQL语句获取动态的数据库,并为其命名],用户使用时只需使用[名称]即可获取结果集.就可以当做表来使用. # 1. ...

  4. (四)js数组方法一

    ES5数组方法: Array.prototype.filter()   对数组元素进行过滤 三个参数:元素值,下标,原数组 返回:过滤后符合条件的数组,不会改变原数组 let arr = [2,4,6 ...

  5. 【vs2013】使用VS2013打包程序

    如何用 VS 2013 打包 程序? 摘自:http://www.zhihu.com/question/25415940 更多请见摘自. 答案就在这里,想要你的exe独立运行在XP中:1.将平台工具集 ...

  6. MYSQL中防止插入重复记录的解决方案(无重复值更新)

    说明:一般我们使用MYSQL插入记录时,类似于这样的语句: insert into table_name(email,phone,user_id) values(‘test9@163.com’,’99 ...

  7. HttpWebRequest传值

    From:发送方 class Program { static void Main(string[] args) { string strId = "zhangsan"; &quo ...

  8. Google网站遭到域名劫持

    今天晚上,包括Google.com在内的绝大多数Google国际网站,例如Google.com.Gmail.Google Reader.Google Docs等,在中国部分省市均出现无法访问的情况. ...

  9. Arcmap10.1下安装ArcBrutile0.2.2 (Win7)(转)

    前阵子换了高级新电脑,用的win7旗舰版装了Arcgis10.1,一直没试过ArcBrutile0.2.2能不能用,今天想用的时候发现自己竟然忘记怎么加载这个工具了!!!   网上搜了一下,度娘今天不 ...

  10. 题目1534:数组中第K小的数字 ——二分

    http://ac.jobdu.com/problem.php?pid=1534 给定两个整型数组A和B.我们将A和B中的元素两两相加可以得到数组C.譬如A为[1,2],B为[3,4].那么由A和B中 ...