LeetCode 4 - 两个排序数组的中位数 - [分治]
题目链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/description/
给定两个大小为 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.5
题解:
考虑转化为求两个有序数组的第 $k$ 小数,
不妨先假设两个有序数组的长度都是大于等于 $c = \left\lfloor {\frac{k}{2}} \right\rfloor$ 的,比较 $A[c]$ 和 $B[c]$,有两种情况:
1、$A[c] \le B[c]$,那么两个数组合并之后,若 $B[1] \sim B[c]$ 的位置越往前靠,相应的 $A[c]$ 就越会往后靠,但显然 $B[c]$ 所在位置的最靠前情况是在第 $2c \le k$ 个,那么 $A[c]$ 所在位置的最差情况就是在第 $2c-1 \le k-1$ 个,因此 $A[1] \sim A[c]$ 必然在前 $k-1$ 小的数之中,可以将 $A[1] \sim A[c]$ 截去,不影响寻找第 $k$ 小数;
2、$A[c] > B[c]$,类似于情况2,可以将 $B[1] \sim B[c]$ 截去。
若两个有序数组的长度存在小于 $c = \left\lfloor {\frac{k}{2}} \right\rfloor$ 的情况呢?首先可以确定的是,就算存在这种情况,也肯定只有其中一个的长度会小于 $c$,
不妨设是 $A$ 数组的长度小于 $c$,那么,可以比较 $A[A.size]$ 和 $B[k-A.size]$,和上面也是一样的道理。
最后处理边界情况:当 $k=1$ 的时候,返回 $A[1]$ 和 $B[1]$ 中小的那一个即可;当两个数组中有一个为空的时候,就返回另一个数组的第 $k$ 个元素。
时间复杂度:
考虑是不断地让 $k$ 除以 $2$,直到 $k=1$ 时停止,故时间复杂度 $O(\log(k)) = O(\log(len)) = O(\log(m+n))$,满足题目要求。
AC代码:
class Solution
{
public:
int getkth(const vector<int>& nums1,int x,const vector<int>& nums2,int y,int k)
{
if(x>=nums1.size()) return nums2[y+k-]; //A数组为空
if(y>=nums2.size()) return nums1[x+k-]; //B数组为空
if(k==) return min(nums1[x],nums2[y]); int c1=min((int)nums1.size()-x,k/);
int c2=min((int)nums2.size()-y,k/);
if(nums1[x+c1-]<=nums2[y+c2-]) return getkth(nums1,x+c1,nums2,y,k-c1);
else return getkth(nums1,x,nums2,y+c2,k-c2);
}
double findMedianSortedArrays(vector<int>& nums1,vector<int>& nums2)
{
int len=nums1.size()+nums2.size();
if(len%) return getkth(nums1,,nums2,,(len+)/);
else return (getkth(nums1,,nums2,,len/)+getkth(nums1,,nums2,,len/+))/2.0;
}
};
这道题目,最令人震惊的是……
我新开一个vector把nums1和nums2的元素都扔进去然后sort了一下,$O(1)$ 输出中位数,明明 $O((m+n) \log(m+n))$ 的时间复杂度,居然和 $O(\log(m+n))$ 跑的一样快,都是52ms……
感觉自己搞了假的时间复杂度……
所以我开始怀疑,是不是LeetCode用了很水数据,实际上大部分时间是在其他什么地方耗费的,果然,关闭IO同步之后可以 16ms 内跑完:
static const auto io_sync_off = []()
{
// turn off sync
std::ios::sync_with_stdio(false);
// untie in/out streams
std::cin.tie(nullptr);
return nullptr;
}();
class Solution
{
public:
inline int getkth(const vector<int>& nums1,int x,const vector<int>& nums2,int y,int k)
{
if(x>=nums1.size()) return nums2[y+k-]; //A数组为空
if(y>=nums2.size()) return nums1[x+k-]; //B数组为空
if(k==) return min(nums1[x],nums2[y]); int c1=min((int)nums1.size()-x,k/);
int c2=min((int)nums2.size()-y,k/);
if(nums1[x+c1-]<=nums2[y+c2-]) return getkth(nums1,x+c1,nums2,y,k-c1);
else return getkth(nums1,x,nums2,y+c2,k-c2);
}
double findMedianSortedArrays(vector<int>& nums1,vector<int>& nums2)
{
int len=nums1.size()+nums2.size();
if(len%) return getkth(nums1,,nums2,,(len+)/);
else return (getkth(nums1,,nums2,,len/)+getkth(nums1,,nums2,,len/+))/2.0;
}
};
我还同样把上面 $O((m+n) \log(m+n))$ 的那个算法关了IO同步试了一下,耗时 32ms……这个 16ms 的差距,应该即使优化复杂度的结果了吧,还算有个安慰。
LeetCode 4 - 两个排序数组的中位数 - [分治]的更多相关文章
- LeetCode#5 两个排序数组的中位数
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个有序数组的中位数.要求算法的时间复杂度为 O(log (m+n)) . 你可以假设 nums1 和 nums2 ...
- leetcode 4.两个排序数组的中位数
题目: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个有序数组的中位数.要求算法的时间复杂度为 O(log (m+n)) . 你可以假设 nums1 和 nums ...
- leetcode,两个排序数组的中位数
先上题目描述: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个有序数组的中位数.要求算法的时间复杂度为 O(log (m+n)) . 你可以假设 nums1 和 ...
- leetcode python两个排序数组的中位数
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个有序数组的中位数.要求算法的时间复杂度为 O(log (m+n)) . 你可以假设 nums1 和 nums2 不同 ...
- LeetCode(4):两个排序数组的中位数
Hard! 题目描述: 有两个大小为 m 和 n 的排序数组 nums1 和 nums2 . 请找出两个排序数组的中位数并且总的运行时间复杂度为 O(log (m+n)) . 示例 1: nums1 ...
- LeetCode4. 两个排序数组的中位数
4. 两个排序数组的中位数 问题描述 There are two sorted arrays nums1 and nums2 of size m and n respectively.Find the ...
- 2.Median of Two Sorted Arrays (两个排序数组的中位数)
要求:Median of Two Sorted Arrays (求两个排序数组的中位数) 分析:1. 两个数组含有的数字总数为偶数或奇数两种情况.2. 有数组可能为空. 解决方法: 1.排序法 时间复 ...
- LeetCode-4. 两个排序数组的中位数(详解)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/description/ 有两个大小为 m 和 n 的排序数组 nums ...
- JavaScript实现获取两个排序数组的中位数算法示例
本文实例讲述了JavaScript排序代码实现获取两个排序数组的中位数算法.分享给大家供大家参考,具体如下: 题目 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个 ...
随机推荐
- Android——Broadcast Receive 相关知识总结贴
Android系统中的广播(Broadcast)机制简要介绍和学习计划 http://www.apkbus.com/android-99858-1-1.html android----BroadCas ...
- Charles for Mac(HTTP 监视器和网络抓包工具)破解版安装
1.软件简介 Charles 是在 Mac.Linux 或 Windows 下常用的 http 协议网络包截取工具,在平常的测试与调式过程中,掌握此工具就基本可以不用其他抓包工具了.Charle ...
- apache的性能调配 MaxClients 与MaxRequestsPerChild
因近期服务不稳定,现象和这个比较类似http://hi.baidu.com/xinfeng999/blog/item/1aea470e214ab1cd7acbe1ed.html根据现象来对APACHE ...
- 深入理解Fsync
1 介绍 数据库系统从诞生那天开始,就面对一个很棘手的问题,fsync的性能问题.组提交(group commit)就是为了解决fsync的问题.最近,遇到一个业务反映MySQL创建分区表很慢,仔细分 ...
- 【Vegas原创】SQL Server 只安装客户端的方法
只安装管理工具
- 转移 Visual Studio 2017 的安装临时文件
每次更新 Visual Studio 2017 会在 C 盘留下大量的缓存文件,因为目录比较深,怕以后忘了,用目录链接的形式转移到其它磁盘,也好方便清理: mklink /D C:\ProgramDa ...
- 趣文分享:有人将Android开发环境比作女人
(一个移动开发者大会活动推荐:http://www.eoeandroid.com/thread-303943-1-1.html) 趣文分享:有人将Android开发环境比作女人 在日常开发工作中,我们 ...
- android 对话框全屏
对话框风格 <style name="Lam.Dialog.FullScreen" parent="@style/Theme.AppCompat.Dialog&qu ...
- [Big Data - ZooKeeper] ZooKeeper: A Distributed Coordination Service for Distributed Applications
ZooKeeper ZooKeeper: A Distributed Coordination Service for Distributed Applications Design Goals Da ...
- FAL_CLIENT和FAL_SERVER参数详解
FAL_CLIENT和FAL_SERVER参数详解 转载:http://openwares.net/database/fal_client_fal_server.html FAL_CLIENT和FAL ...