大家好,我是老皮;

题目地址:https://leetcode.com/problems/median-of-two-sorted-arrays/

题目描述:

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。你可以假设 nums1 和 nums2 不会同时为空。示例 1:nums1 = [1, 3]nums2 = [2]则中位数是 2.0示例 2:nums1 = [1, 2]nums2 = [3, 4]则中位数是 (2 + 3)/2 = 2.

来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:

首先了解一下Median的概念,一个数组中median就是把数组分成左右等分的中位数。如下图:这道题,很容易想到暴力解法,时间复杂度和空间复杂度都是 O(m+n), 不符合题中给出 O(log(m+n))时间复杂度的要求。我们可以从简单的解法入手,试了一下,暴力解法也是可以被Leetcode Accept的. 分析中会给出两种解法,暴力求解和二分解法。01

解法一:暴力 (Brute Force)

暴力解主要是要merge两个排序的数组 (A,B)成一个排序的数组。用两个 pointer(i,j), i 从数组 A起始位置开始,即 i=0开始, j 从数组 B起始位置, 即 j=0开始. 一一比较 A[i]和B[j]

  1. 如果 A[i]<=B[j], 则把 A[i] 放入新的数组中,i往后移一位,即 i+1.
  2. 如果 A[i]>B[j], 则把 B[j] 放入新的数组中,j往后移一位,即 j+1.
  3. 重复步骤#1 和 #2,直到 i移到 A最后,或者 j移到 B最后。
  4. 如果 j移动到 B数组最后,那么直接把剩下的所有 A依次放入新的数组中.
  5. 如果 i移动到 A数组最后,那么直接把剩下的所有 B依次放入新的数组中.

Merge的过程如下图。时间复杂度:O(m+n)-mislength of A,nislength of B空间复杂度:O(m+n)02

解法二:二分查找 (Binary Search)

由于题中给出的数组都是排好序的,在排好序的数组中查找很容易想到可以用二分查找(Binary Search)。这里对数组长度小的做二分, 保证数组A 和 数组B 做partition 之后,len(Aleft)+len(Bleft)=(m+n+1)/2-m是数组A的长度,n是数组B的长度,对数组A的做partition的位置是区间 [0,m]。如图:下图给出几种不同情况的例子(注意但左边或者右边没有元素的时候,左边用 INF_MIN,右边用 INF_MAX表示左右的元素:下图给出具体做的partition 解题的例子步骤:时间复杂度:O(log(min(m,n))-mislength of A,nislength of B空间复杂度:O(1) - 这里没有用额外的空间。03

关键点分析

  1. 暴力求解,在线性时间内merge两个排好序的数组成一个数组。
  2. 二分查找,关键点在于:
  • 要partition两个排好序的数组成左右两等份,partition需要满足 len(Aleft)+len(Bleft)=(m+n+1)/2 - m是数组A的长度, n是数组B的长度
  • 并且partition后 A左边最大( maxLeftA), A右边最小( minRightA), B左边最大( maxLeftB), B右边最小( minRightB) 满足 (maxLeftA <= minRightB && maxLeftB <= minRightA)

有了这两个条件,那么median就在这四个数中,根据奇数或者是偶数

奇数:median = max(maxLeftA, maxLeftB)偶数:median = (max(maxLeftA, maxLeftB) + min(minRightA, minRightB)) / 2

04

代码(Java code)

解法一:暴力解法(Brute force)

class MedianTwoSortedArrayBruteForce {public double findMedianSortedArrays(int[] nums1, int[] nums2) {int[] newArr = mergeTwoSortedArray(nums1, nums2);int n = newArr.length;if (n % 2 == 0) {// evenreturn (double) (newArr[n / 2] + newArr[n / 2 - 1]) / 2;} else {// oddreturn (double) newArr[n / 2];}}private int[] mergeTwoSortedArray(int[] nums1, int[] nums2) {int m = nums1.length;int n = nums2.length;int[] res = new int[m + n];int i = 0;int j = 0;int idx = 0;while (i m && j if (nums1[i] <= nums2[j]) {          res[idx++] = nums1[i++];} else {          res[idx++] = nums2[j++];}}while (i m) {        res[idx++] = nums1[i++];}while (j return res;}}

解法二:二分查找(Binary Search)

class MedianSortedTwoArrayBinarySearch {public static double findMedianSortedArraysBinarySearch(int[] nums1, int[] nums2) {// do binary search for shorter length array, make sure time complexity log(min(m,n)).if (nums1.length > nums2.length) {return findMedianSortedArraysBinarySearch(nums2, nums1);}int m = nums1.length;int n = nums2.length;int lo = 0;int hi = m;while (lo <= hi) {// partition A position iint i = lo + (hi - lo) / 2;// partition B position jint j = (m + n + 1) / 2 - i;int maxLeftA = i == 0 ? Integer.MIN_VALUE : nums1[i - 1];int minRightA = i == m ? Integer.MAX_VALUE : nums1[i];int maxLeftB = j == 0 ? Integer.MIN_VALUE : nums2[j - 1];int minRightB = j == n ? Integer.MAX_VALUE : nums2[j];if (maxLeftA <= minRightB && maxLeftB <= minRightA) {// total length is evenif ((m + n) % 2 == 0) {return (double) (Math.max(maxLeftA, maxLeftB) + Math.min(minRightA, minRightB)) / 2;} else {// total length is oddreturn (double) Math.max(maxLeftA, maxLeftB);}} else if (maxLeftA > minRightB) {// binary search left half          hi = i - 1;} else {// binary search right half          lo = i + 1;}}return 0.0;}}

double 数组_寻找两个有序数组的中位数相关推荐

  1. 算法--------------------寻找两个有序数组的中位数

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

  2. LeetCode4. 寻找两个有序数组的中位数

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

  3. 20191016:(leetcode习题)寻找两个有序数组的中位数

    寻找两个有序数组的中位数 题目 大致思路 代码实现 题目 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log( ...

  4. 分享一道力扣困难题~寻找两个有序数组的中位数(Java)

    目录 解题思路1 具体代码 解题思路2 具体代码 题目描述:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的 中位数 .算法的时间复杂 ...

  5. 两个有序数组的中位数 python_Python寻找两个有序数组的中位数实例详解

    Python寻找两个有序数组的中位数 审题: 1.找出意味着这是一个查找算法题 2.算法复杂度log级别,就是提示你是二分查找 3.二分查找实现一般为递归 (1)递归包括递归体 (2)终止条件 思路: ...

  6. (JS)寻找两个有序数组的中位数

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

  7. Python寻找两个有序数组的中位数

    Python寻找两个有序数组的中位数 审题: 找出意味着这是一个查找算法题 算法复杂度log级别,就是提示你是二分查找 二分查找实现一般为递归 (1)递归包括递归体 (2)终止条件 思路: 定理: 有 ...

  8. 力扣寻找两个有序数组的中位数

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

  9. LeetCode(Python实现)—寻找两个有序数组的中位数

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

最新文章

  1. linux proc
  2. Spring Data JPA 与 MyBatis 对比,你喜欢用哪个?
  3. sqlserver中int 类型的字段,值为null的时候引发一个问题
  4. cura-engine学习(1)
  5. Visual Studio Code 常用插件整理
  6. python去掉字符串中空格的方法
  7. maf中anglearc_Oracle MAF中的LOV
  8. CString LPCTSTR LPTSTR 类型的相互转化
  9. mysql中起飞到达城市查询_让mysql慢慢起飞 - 初识慢日志
  10. “我xx岁了,想学软件测试,现在转行来得及吗?”别再问了,这篇文章终结此类问题
  11. Sublime Text3之安裝Emmet及使用技巧
  12. 一种类型安全的Java HTTP客户端库Retrofit
  13. HDU-1150 Machine Schedule 二分图匹配
  14. c语言关键用法大全,c语言关键字的用法详解
  15. python软件安装链接电视_Python爬虫程序:电视剧琅琊榜全集的自动化处理
  16. Linux网易云问题(高分屏)
  17. Android SDK (介绍)
  18. 在场景中增加固定自定义栏
  19. CAD如何使用几何约束命令将多个圆合并成为一个同心圆呢?
  20. C#获取网络时间(初学者)

热门文章

  1. 改:今天看到的一个有趣面试题:return *this和return this有什么区别?
  2. 【自动驾驶】13. Apollo交通信号灯感知
  3. 训练深度神经网络的时候需要注意的一些小技巧
  4. 浅谈 Java 字符串(String, StringBuffer, StringBuilder)
  5. 用Python和OpenCV提取颜色直方图特征
  6. 局部特征(5)——如何利用彩色信息 Color Descriptors
  7. 编程之美-计算字符串的相似度方法整理
  8. 使用Windows PowerShell管理虚拟交换机
  9. python-学习 协程函数 模块与包
  10. 10个最佳Node.js企业应用案例:从Uber到LinkedIn