leetcode 4寻找两个有序数组的中位数

最优解O(log(min(m,n)))
/**
之前用合并有序数组的思想做了O((m+n+1)/2),现在试一试O(log(min(m,n)))
基本思路为:通过二分查找较小的数组得到对应的中位数(假设存在,越界的情况最后套路)
假设分别为n1,n2,必有n1<=n2,假设最后找的两个可能的中位数是m1,m2个数(还是先假设存在)
那么二分查找nums1时,初始值left=0,right=n1;则m1 有[0,n1],m2有[k-n1,n1](k-n1>=0必然成立)
而n1<=n2,所以m2一定在[0,n2]之间,因此遍历小数组并不需要担心越界的事情,只需要在最后处理0和n1,n2的特殊情况;
***/ class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
//首先检测是否是小数组在前,大数组在后
const int n1=nums1.size();
const int n2=nums2.size();
if(n1>n2) return findMedianSortedArrays(nums2,nums1); int m1,m2;
int left=,right=n1,k=(n1+n2+)/;
//二分查找m1,m2(假设存在)
while(left<right){
m1=left+(right-left)/;
m2=k-m1;
if(nums1[m1]<nums2[m2-])
left=m1+;
else
right=m1;
}
m1=left;
m2=k-m1; int c1,c2;
//找到第一个数c1,如果总共为奇数个,返回结果
c1=max(m1<=?INT_MIN:nums1[m1-],m2<=?INT_MIN:nums2[m2-]);
if((n1+n2)&==)
return c1; //找到第二个数c2,并返回(c1+c2)/2
c2=min(m1>=n1?INT_MAX:nums1[m1],m2>=n2?INT_MAX:nums2[m2]);
return double(c1+c2)*0.5;
}
};
方法二:合并有序数组
O(log(m+n+1)/2)
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
//time O(m+n+1)/2 space O(n)的解,获得两个num1的size(),分别用两个指针指向两个数组,每次把较小的向后移位
int n1=nums1.size();int n2=nums2.size();
int id1,id2;
int mid=(n1+n2+)/;
int i=,j=;
int cur=INT_MIN;
while(mid!=&&i<n1&&j<n2){
mid--;
if(nums1[i]<nums2[j])
id1=nums1[i++];
else
id1=nums2[j++];
}
while(mid!=&&i<n1){
mid--;
id1=nums1[i++];
}
while(mid!=&&j<n2){
mid--;
id1=nums2[j++];
}
if((n1+n2)%==) return id1;
id2=min((j>=n2?INT_MAX:nums2[j]),(i>=n1?INT_MAX:nums1[i]));
return double(id1+id2)*0.5;
}
};
附上二分法的分析过程:

总结一下:
1. m1<=0时,c1=nums2[m2-1],在4不成立时,c2=min(nums1[m1],nums2[m2]);
2. m2<=0时,c1=nums1[m1-1],c2=nums2[m2],此时实际上m2=0,m1=n1而且n1=n2=k;
3. m1>=n1,c2=nums2[m2],在2不成立时,c1=max(nums1[m1-1],nums2[m2-1]);
4. m2>=n2,c2=nums1[m1],c1=nums2[m2-1],此时实际上m1=0,m2=n2而且n1=n2=k;
因此容易理解的返回可以这么写
//
if(m2<=){//此时m1>=n1成立
c1=nums1[m1-],c2=nums2[m2];
}
//
if(m2>=n2){//此时m1<=0成立
c1=nums2[m2-],c2=nums1[m1];
}
//
if(m1<=){
c1=nums2[m2-],c2=min(nums1[m1],nums2[m2]);
}
//
if(m1>=n1){
c1=max(nums1[m1-],nums2[m2-]),c2=nums2[m2];
} //对于c1,可知当m1<=0成立时应该选nums2[m2-1](2、3),当m2<=0成立时应该选择nums1[m1-1](1),当两个都不成立取两者最大值(4),由于题给条件两者不可能都成立除非nums1,nums2都为空
c1=max(m1<=?INT_MIN:nums1[m1-],m2<=?INT_MIN:nums2[m2-]);
//对于c2,可知当m1>=n1成立时应该选nums2[m2](1、4),当m2>=n2成立时应该选择nums1[m1](2),当两者都不成立时取最小值(3),同样由于提给条件两者不可能都成立;
c2=min(m1>=n1?INT_MAX:nums1[m1],m2>=n2?INT_MAX:nums2[m2]);
leetcode 4寻找两个有序数组的中位数的更多相关文章
- Java实现 LeetCode 4 寻找两个有序数组的中位数
寻找两个有序数组的中位数 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 n ...
- 【LeetCode】寻找两个有序数组的中位数【性质分析+二分】
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 nums2 ...
- [LeetCode] 4. 寻找两个有序数组的中位数
题目链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/ 题目描述: 给定两个大小为 m 和 n 的有序数组 nums1 和 ...
- 【LeetCode】寻找两个有序数组的中位数
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 nums2 ...
- leetcode 4 寻找两个有序数组的中位数 二分法&INT_MAX
小知识 INT_MIN在标准头文件limits.h中定义. #define INT_MAX 2147483647#define INT_MIN (-INT_MAX - 1) 题解思路 其实是类似的二分 ...
- LeetCode Golang 4. 寻找两个有序数组的中位数
4. 寻找两个有序数组的中位数 很明显我偷了懒, 没有给出正确的算法,因为官方的解法需要时间仔细看一下... func findMedianSortedArrays(nums1 []int, nums ...
- Leetcode(4)寻找两个有序数组的中位数
Leetcode(4)寻找两个有序数组的中位数 [题目表述]: 给定两个大小为 m 和 n 的有序数组 nums1 和* nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O( ...
- 0004. 寻找两个有序数组的中位数(Java)
4. 寻找两个有序数组的中位数 https://leetcode-cn.com/problems/median-of-two-sorted-arrays/ 最简单的就是用最简单的,把两个数组分别抽出然 ...
- leetcode题目4.寻找两个有序数组的中位数(困难)
题目描述: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 ...
随机推荐
- uoj #450[集训队作业2018]复读机
传送门 \(d=1\),那么任何时刻都可以\(k\)个复读机的一种,答案为\(k^n\) \(d>1\),可以枚举某个复读机的复读次数(必须是\(d\)的倍数),然后第\(i\)个复读时间为\( ...
- 使用elasticdump导入导出数据
一.安装elasticdump 终端中输入 npm install elasticdump -g -g表示全局可用,直接在终端输入 elasticdump --version,出现版本信息即表示安装成 ...
- drf三大认证解析
目录 三大认证 认证模块: 权限模块 频率模块 RABC author组件 认证权限六表. Content_type 认证与权限工作原理+自定义认证类 自定义权限类 admin关联自定义用户表 前后台 ...
- vue.js 分页加载,向上滑动,依次加载数据。
export default { layout: 'default', data(){ return{ page:1, pageSize:10, orderListArr:[], prodListLo ...
- 阿里服务器+Centos7.4+Tomcat+JDK部署
适用对象 本文档介绍如何使用一台基本配置的云服务器 ECS 实例部署 Java web 项目.适用于刚开始使用阿里云进行建站的个人用户. 配置要求 这里列出的软件版本仅代表写作本文档使用的版本.操作时 ...
- IBM小机拆镜像换盘
1.硬盘告警信息 2.故障排查 查看错误日志 # errpt -aj C62E1EB7 查看hdisk0的信息,发现hdisk0属于rootvg # lspv 查看hdi ...
- mysql占用磁盘IO过高的解决办法
一.现象 最近发现Mysql服务器磁盘IO一直很高 [root@push-- ~]# iostat -k -d -x Linux -.el7.x86_64 (push--) 2019年07月05日 _ ...
- Python核心技术与实战——十七|Python并发编程之Futures
不论是哪一种语言,并发编程都是一项非常重要的技巧.比如我们上一章用的爬虫,就被广泛用在工业的各个领域.我们每天在各个网站.App上获取的新闻信息,很大一部分都是通过并发编程版本的爬虫获得的. 正确并合 ...
- python-进程、线程与协程
基础概念 进程 是一个执行中的程序,即将程序装载到内存中,系统为它分配资源的这一过程.进程是操作系统资源分配的基本单位. 每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text regio ...
- 解决ios横屏拍照图片自动旋转90度问题
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...