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. tp3 save操作小bug误区

    $china_area->save(['is_del' => 1,'updatetime' => time()]); SHOW COLUMNS FROM `tf_china_area ...

  2. django中命令行调试程序

    (1)进入到程序manage.py所在的目录下 (2)python manage.py shell 这样可在命令行中引入models.views.class等所有的包,然后进行命令行试运行.

  3. Gulp小记

    安装 总的来说,玩gulp的流程是这样的: 安装nodejs -> 全局安装gulp -> 项目安装gulp以及gulp插件 -> 配置gulpfile.js -> 运行任务 ...

  4. Python新手入门英文词汇笔记(转)

    一.交互式环境与print输出 1.print:打印/输出2.coding:编码3.syntax:语法4.error:错误5.invalid:无效6.identifier:名称/标识符7.charac ...

  5. ElasticSearch 批量增加索引

    服务端批量增加索引,版本是5.1.1 TransportClient client; Settings esSettings = Settings.builder() .put("clust ...

  6. springboot下实现邮件发送功能

    springboot给我们封装好了邮件功能,非常简单,只需要稍微配置下就ok. 引入jar <dependency> <groupId>org.springframework. ...

  7. c# 打印 bartender

    参考: 官网  https://www.seagullscientific.com/label-software/barcode-label-design-and-printing 文章 http:/ ...

  8. Docker 入门 第三部分: 服务

    目录 Docker 入门 第三部分: 服务 先决条件 介绍 你的第一个 docker-compose.yml 文件 docker-compose.yml 运行你新建的负载均衡应用 扩展应用程序 卸载应 ...

  9. Oracle——存储过程简单入门实例

    1.连接plsql developer,打开一个SQL Window 2.SQL Window中创建表user_info -- Create table create table USER_INFO ...

  10. Linux之安装虚拟机/虚拟操作系统[VisualBox]

    使用VisualBox安装虚拟机步骤: BIOS开启 Visual Technology(或者 visualization) 安装Visual Box 打开Visual Box > 新建虚拟电脑 ...