Hard!

题目描述:

有两个大小为 m 和 n 的排序数组 nums1 和 nums2 。

请找出两个排序数组的中位数并且总的运行时间复杂度为 O(log (m+n)) 。

示例 1:

nums1 = [1, 3]
nums2 = [2] 中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4] 中位数是 (2 + 3)/2 = 2.5

解题思路:

这道题让我们求两个有序数组的中位数,而且限制了时间复杂度为O(log (m+n)),看到这个时间复杂度,自然而然的想到了应该使用二分查找法来求解。但是这道题被定义为Hard也是有其原因的,难就难在要在两个未合并的有序数组之间使用二分法,这里我们需要定义一个函数来找到第K个元素,由于两个数组长度之和的奇偶不确定,因此需要分情况来讨论,对于奇数的情况,直接找到最中间的数即可,偶数的话需要求最中间两个数的平均值。下面重点来看如何实现找到第K个元素,首先我们需要让数组1的长度小于或等于数组2的长度,那么我们只需判断如果数组1的长度大于数组2的长度的话,交换两个数组即可,然后我们要判断小的数组是否为空,为空的话,直接在另一个数组找第K个即可。还有一种情况是当K = 1时,表示我们要找第一个元素,只要比较两个数组的第一个元素,返回较小的那个即可。

知识点回顾:

中位数的概念

中位数(又称中值,英语:Median),统计学中的专有名词,代表一个样本、种群或概率分布中的一个数值,其可将数值集合划分为相等的上下两部分。
对于有限的数集,可以通过把所有观察值高低排序后找出正中间的一个作为中位数。如果观察值有偶数个,通常取最中间的两个数值的平均数作为中位数。
 
 C++参考答案一:
 class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int total = nums1.size() + nums2.size();
if (total % == ) {
return findKth(nums1, , nums2, , total / + );
} else {
return (findKth(nums1, , nums2, , total / ) + findKth(nums1, , nums2, , total / + )) / ;
}
}
double findKth(vector<int> &nums1, int i, vector<int> &nums2, int j, int k) {
if (nums1.size() - i > nums2.size() - j) return findKth(nums2, j, nums1, i, k);
if (nums1.size() == i) return nums2[j + k - ];
if (k == ) return min(nums1[i], nums2[j]);
int pa = min(i + k / , int(nums1.size())), pb = j + k - pa + i;
if (nums1[pa - ] < nums2[pb - ])
return findKth(nums1, pa, nums2, j, k - pa + i);
else if (nums1[pa - ] > nums2[pb - ])
return findKth(nums1, i, nums2, pb, k - pb + j);
else
return nums1[pa - ];
}
};

上面的方法变量太多,较为复杂,我们也可以通过在findKth函数中改变数组元素的个数来去掉一些变量,使代码整体看起来更加简洁清楚,参见代码如下:

 C++参考答案二:

 class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m = nums1.size(), n = nums2.size();
return (findKth(nums1, nums2, (m + n + ) / ) + findKth(nums1, nums2, (m + n + ) / )) / 2.0;
}
int findKth(vector<int> nums1, vector<int> nums2, int k) {
int m = nums1.size(), n = nums2.size();
if (m > n) return findKth(nums2, nums1, k);
if (m == ) return nums2[k - ];
if (k == ) return min(nums1[], nums2[]);
int i = min(m, k / ), j = min(n, k / );
if (nums1[i - ] > nums2[j - ]) {
return findKth(nums1, vector<int>(nums2.begin() + j, nums2.end()), k - j);
} else {
return findKth(vector<int>(nums1.begin() + i, nums1.end()), nums2, k - i);
}
return ;
}
};

此题还能用二分搜索法来解,是一种相当巧妙的应用。讲解详见:https://leetcode.com/problems/median-of-two-sorted-arrays/discuss/2471/very-concise-ologminmn-iterative-solution-with-detailed-explanation

C++参考答案三:

 class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m = nums1.size(), n = nums2.size();
if (m < n) return findMedianSortedArrays(nums2, nums1);
if (n == ) return ((double)nums1[(m - ) / ] + (double)nums1[m / ]) / 2.0;
int left = , right = n * ;
while (left <= right) {
int mid2 = (left + right) / ;
int mid1 = m + n - mid2;
double L1 = mid1 == ? INT_MIN : nums1[(mid1 - ) / ];
double L2 = mid2 == ? INT_MIN : nums2[(mid2 - ) / ];
double R1 = mid1 == m * ? INT_MAX : nums1[mid1 / ];
double R2 = mid2 == n * ? INT_MAX : nums2[mid2 / ];
if (L1 > R2) left = mid2 + ;
else if (L2 > R1) right = mid2 - ;
else return (max(L1, L2) + min(R1, R2)) / ;
}
return -;
}
};

LeetCode(4):两个排序数组的中位数的更多相关文章

  1. LeetCode 4 - 两个排序数组的中位数 - [分治]

    题目链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/description/ 给定两个大小为 m 和 n 的有序数组 n ...

  2. LeetCode#5 两个排序数组的中位数

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

  3. leetcode 4.两个排序数组的中位数

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

  4. leetcode,两个排序数组的中位数

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

  5. leetcode python两个排序数组的中位数

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

  6. LeetCode4. 两个排序数组的中位数

    4. 两个排序数组的中位数 问题描述 There are two sorted arrays nums1 and nums2 of size m and n respectively.Find the ...

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

    要求:Median of Two Sorted Arrays (求两个排序数组的中位数) 分析:1. 两个数组含有的数字总数为偶数或奇数两种情况.2. 有数组可能为空. 解决方法: 1.排序法 时间复 ...

  8. LeetCode-4. 两个排序数组的中位数(详解)

    链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/description/ 有两个大小为 m 和 n 的排序数组 nums ...

  9. JavaScript实现获取两个排序数组的中位数算法示例

    本文实例讲述了JavaScript排序代码实现获取两个排序数组的中位数算法.分享给大家供大家参考,具体如下: 题目 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个 ...

随机推荐

  1. nginx location详解

    Location block 的基本语法形式是: location [=|~|~*|^~|@] pattern { ... } [=|~|~*|^~|@] 被称作 location modifier ...

  2. Java 读取文件的内容

    Java 读取文件的内容 1) CLASS_NAME: 换成自己真实的类名 2) /page/test.json: 换成自己真实的page 3) FileUtils: 来自于org.apache.co ...

  3. java程序中加入@SuppressWarnings("serial")是什么意思?

    比如有个类实现了java.io.Serialize接口:package com.onede4.test; public class TestSerial implements java.io.Seri ...

  4. UDP网路会议室的代码

    UDP网络会议室视频已经录制好,这里贴上代码仅供参考 MainWindow代码: using System; using System.Collections.Generic; using Syste ...

  5. javascript Date定义和体验

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Hbase记录-HBase增删改查

    HBase创建数据   本章将介绍如何在HBase表中创建的数据.要在HBase表中创建的数据,可以下面的命令和方法: put 命令, add() - Put类的方法 put() - HTable 类 ...

  7. keepalive+nginx 热备跟负载均衡

    结构图 keepalived配置 master跟backup除了state跟优先级,其它一样,优先级master需大于backup ! Configuration File for keepalive ...

  8. hud 2554 N对数的排列问题 (规律)

    题目链接 Problem Description 有N对双胞胎,他们的年龄分别是1,2,3,--,N岁,他们手拉手排成一队到野外去玩,要经过一根独木桥,为了安全起见,要求年龄大的和年龄小的排在一起,好 ...

  9. Java 学习札记(二)TomCat安装配置

    1.下载TomCat 下载地址:http://tomcat.apache.org/ 2.配置环境变量 CATALINA_HOME:F:\JAVA\apache-tomcat-6.0.18\apache ...

  10. Handler实现与机制 && Blocking Queue && IdleHandler使用

    http://blog.csdn.net/boyupeng/article/details/46685343 IdleHandler处理消息的源码 final Message next() { ... ...