最优解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寻找两个有序数组的中位数的更多相关文章

  1. Java实现 LeetCode 4 寻找两个有序数组的中位数

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

  2. 【LeetCode】寻找两个有序数组的中位数【性质分析+二分】

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

  3. [LeetCode] 4. 寻找两个有序数组的中位数

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

  4. 【LeetCode】寻找两个有序数组的中位数

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

  5. leetcode 4 寻找两个有序数组的中位数 二分法&INT_MAX

    小知识 INT_MIN在标准头文件limits.h中定义. #define INT_MAX 2147483647#define INT_MIN (-INT_MAX - 1) 题解思路 其实是类似的二分 ...

  6. LeetCode Golang 4. 寻找两个有序数组的中位数

    4. 寻找两个有序数组的中位数 很明显我偷了懒, 没有给出正确的算法,因为官方的解法需要时间仔细看一下... func findMedianSortedArrays(nums1 []int, nums ...

  7. Leetcode(4)寻找两个有序数组的中位数

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

  8. 0004. 寻找两个有序数组的中位数(Java)

    4. 寻找两个有序数组的中位数 https://leetcode-cn.com/problems/median-of-two-sorted-arrays/ 最简单的就是用最简单的,把两个数组分别抽出然 ...

  9. leetcode题目4.寻找两个有序数组的中位数(困难)

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

随机推荐

  1. xml的解析及案例的分析和分享

    HTML的文档如下: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset=& ...

  2. python 服务器 cpu 监控程序--转

    后台 py 代码 app.py ''' 服务器cpu监控程序 思路:后端后台线程一旦产生数据,即刻推送至前端. 好处:不需要前端ajax定时查询,节省服务器资源. 作者:hhh5460 时间:2017 ...

  3. 2019-11-29-msbuild-项目文件常用判断条件

    title author date CreateTime categories msbuild 项目文件常用判断条件 lindexi 2019-11-29 08:36:48 +0800 2019-7- ...

  4. c字符串函数

    1.  bcmp(3) 类ma似于strncmp(3) 但是比较结果不一定是两个字符的ascii码之差. 返回值:相等0,不相等非零(不一定是-1) 2.bcopy(3)类ma似于strncpy(3) ...

  5. zabbix服务的布置(脚本)

    一,服务端配置 #!/bin/bash#clsn #设置解析 注意:网络条件较好时,可以不用自建yum源# echo '10.0.0.1 mirrors.aliyuncs.com mirrors.al ...

  6. mybatis javabean字段与数据库字段的映射

    结论:未作映射的字段没有值,但是数据库中实际是有值的,说明如果带下划线的字段未作映射,返回值是不会有值的,只有映射了的字段以及不带下划线的字段(默认映射)才有返回值 1.bean属性 public c ...

  7. ks代码助解

    代码实现: data_test_2 = {'gd':[1,1,1,1,1,1,0,0,0,0,0,0,0],'score':[1,2,0,2,2,7,4,5,4,0,4,18,np.nan]} dat ...

  8. pt-align的用法简要记录

    pt-align的用法简要记录 1.pt-align 功能:将其它工具的输出按列对齐用法:pt-align [FILES]如果没有指定文件,则默认读取标准输入的内容. 2.例如: [root@dbte ...

  9. Java 集合基础详细介绍

    一.Java集合框架概述 集合.数组都是对多个数据进行存储操作的结构,简称Java容器.此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储(.txt, .jpg, .avi,数据库中).Jav ...

  10. PROP_ENTRY_TYPE用法

    最近几天刚换了vs2019,然后各种水土不服 这不 刚建了一个ATL组件,发现添加了属性编译不过,提示: 错误 C4995 “PROP_ENTRY”: 名称被标记为 #pragma deprecate ...