给定两个大小为 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

思考:

看了Grandyang的博客,慢慢想明白才写的!真的是很细心耐心的博主!

限制了时间复杂度为O(log (m+n)),想到了应该使用二分查找法来求解。

寻找数组的中位数的小技巧假设数组的长度是m,找第(m+1)/2位和第(m+2)/2位的元素,两者的平均数即为数组的中位数

我们可以在两个数组之间使用二分查找。分别去查找每个数组的(m+n+1)/2的元素和(m+n+2)/2的元素求平均数。

首先:定义一个函数来在两个有序数组中找到第K个元素(这道题可以出成:两个有序数组找第N大)

有两个边缘情况要注意:

1、当数组的起始位置已经大于等于数组的长度(这时只用去寻找另一个数组即可),此时表明这个数组中所有元素已经被排除了,所以直接去寻找另一个数组起始位置:j + k /2 -1的元素。

2、当K == 1时,表示要查找当前数组的首元素,举个例子如下图:

算法思路:

分别在nums1和nums2中查找第K/2个元素,数组长度是不定的,所以要确定当前的数组有没有k/2个元素,如果存在就取作midval值,否则就赋值上一个整型最大值INT_MAX。如果某个数组没有第K/2个数字,那么我们就淘汰另一个数组的前K/2个数字即可若找到的midVal1 大于 midVal2,说明该去查找num1的下半区间[i +k/2 -1 +1,end]  (i+k/2 -1 :mid 另外一半区间应该是起始mid +1 ),有序数组的中位数,左边的都比它小,右边的都比它大。

重点理解:“如果某个数组没有第K/2个数字,那么我们就淘汰另一个数组的前K/2个数字即可。

一开始没理解后来主动问了博主:Grandyang。举例子:假设nums1 ={3},nums2={2,4,5,6,7},K=4,我们要在两个数组中找第四个的元素,分别在nums1和nums2中找第2个的元素,现在nums1只有一个数字,所以不存在第二大的数字,而nums2前两个数字可以直接跳过。

因为要求整个两个数组中第4个的元素,如果num1中数字大于num2第k/2位,那么合并之后也是在num2第k/2位之后,而num2的前k/2位是没用的,直接跳过;如果num1中数字是小于num2第k/2位置,但是元素个数是小于k/2,即使合并,这两部分元素个数也只小于k个,所以也不可能在num2的k/2部分,所以第4个的元素肯定不会出现在一个排序数组nums2的前两位,所以可以直接跳过。


/*查找两个数组中排列第K个数*/
int findKthNumber(vector<int>& nums1,int i ,vector<int>& nums2,int j,int k){if(i >= nums1.size())   return nums2[j+k-1];if(j >= nums2.size())   return nums1[i+k-1];//if(k ==1) return (double(nums1[i] + nums2[j]));wrongif(k == 1) return min(nums1[i],nums2[j]);//查找有没有k/2个元素int midVal1 = (i+k/2-1 < nums1.size())?nums1[i+k/2-1]:INT_MAX;int midVal2 = (j+k/2-1 < nums2.size())?nums2[j+k/2-1]:INT_MAX;if(midVal1 < midVal2)/*二分查找,丢弃前半部分包括正中间的数,因为二分查找正是利用中间的数来进行比较*/return findKthNumber(nums1,i+k/2,nums2,j,k-k/2);elsereturn findKthNumber(nums1,i,nums2,j+k/2,k-k/2);
}

还有一个地方值得注意:二分查找的时候,是利用中间数位的值进行比较,所以下一次递归的起始位置就应该从mid+1开始,或者截止位置到mid-1。

整体代码:

/*分清 起始位置 和 第几个元素 */
int findKthNumber(vector<int>& nums1,int i ,vector<int>& nums2,int j,int k){if(i >= nums1.size())   return nums2[j+k-1];if(j >= nums2.size())   return nums1[i+k-1];//if(k ==1) return (double(nums1[i] + nums2[j]));wrongif(k == 1) return min(nums1[i],nums2[j]);//查找有没有k/2个元素的位置     i + k/2 -1 int midVal1 = (i+k/2-1 < nums1.size())?nums1[i+k/2-1]:INT_MAX;int midVal2 = (j+k/2-1 < nums2.size())?nums2[j+k/2-1]:INT_MAX;if(midVal1 < midVal2)return findKthNumber(nums1,i+k/2,nums2,j,k-k/2);elsereturn findKthNumber(nums1,i,nums2,j+k/2,k-k/2);
}
class Solution {
public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int m = nums1.size(),n = nums2.size();int left = (m+n+1)/2,right = (m+n+2)/2;return        (findKthNumber(nums1,0,nums2,0,left)+findKthNumber(nums1,0,nums2,0,right))/2.0;}
};

4. 寻找两个有序数组的中位数(☆☆☆)相关推荐

  1. 算法--------------------寻找两个有序数组的中位数

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

  2. 两个有序数组的中位数 python_Python寻找两个有序数组的中位数实例详解

    Python寻找两个有序数组的中位数 审题: 1.找出意味着这是一个查找算法题 2.算法复杂度log级别,就是提示你是二分查找 3.二分查找实现一般为递归 (1)递归包括递归体 (2)终止条件 思路: ...

  3. LeetCode4. 寻找两个有序数组的中位数

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

  4. 20191016:(leetcode习题)寻找两个有序数组的中位数

    寻找两个有序数组的中位数 题目 大致思路 代码实现 题目 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log( ...

  5. (JS)寻找两个有序数组的中位数

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

  6. Python寻找两个有序数组的中位数

    Python寻找两个有序数组的中位数 审题: 找出意味着这是一个查找算法题 算法复杂度log级别,就是提示你是二分查找 二分查找实现一般为递归 (1)递归包括递归体 (2)终止条件 思路: 定理: 有 ...

  7. 力扣寻找两个有序数组的中位数

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

  8. LeetCode(Python实现)—寻找两个有序数组的中位数

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

  9. 分享一道力扣困难题~寻找两个有序数组的中位数(Java)

    目录 解题思路1 具体代码 解题思路2 具体代码 题目描述:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的 中位数 .算法的时间复杂 ...

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

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

最新文章

  1. 2345浏览器网址_2345网址导航回应“浏览器主页劫持”丨开发者日报
  2. 【10】青龙面板之JD ck 获取的1种办法
  3. bootstrap 起步
  4. 微信小程序 自定义tabBar
  5. javascript调用一个函数(对象),new和直接调用的区别
  6. 0x01第一个汇编程序
  7. LVS学习笔记 5高可用集群原理
  8. 2020年,程序员如何优雅地赚更多的钱?
  9. CAD图纸打印出来后很多CAD文字消失了怎么办?
  10. Android屏幕截图实现方式 系统截屏源码分析和三指截屏
  11. 【马红“名师+”研修共同体成员风采】
  12. 超详细的《使用腾讯云移动直播开发连麦》
  13. 2020年中国SCADA行业产值、市场规模及竞争格局分析[图]
  14. Connection could not be established with host smtp.163.com 阿星小栈
  15. 使用C++实现FC红白机模拟器 Cartridge 与 Mapper(实现篇)
  16. FPGA实现JPEG-LS图像压缩,有损无损可配置,提供工程源码和技术支持
  17. MKR基于知识图谱的推荐算法
  18. 博途PLC的模糊PID(Matlab “fuzzy“工具箱使用介绍)
  19. Windows 11 蓝屏 Stop code - SYSTEM SERVICE EXCEPTION What failed - igdkmd64.sys
  20. git 同步服务器上最新的代码

热门文章

  1. BootStrap Div居中
  2. 梦想CAD控件COM接口光栅图处理
  3. 组织健康度是什么?组织架构调整是实现组织健康的良药吗?
  4. 用钉钉属于计算机什么领域,钉钉密聊支持电脑吗?密聊有哪三种等级?
  5. android9彩蛋小米,外媒曝光小米9外观配置 运行基于Android P的MIUI 10系统
  6. MySQL数据库---SQL语句优化及性能优化
  7. 盘点一款Python二级考试模拟软件,带你轻松过关二级Python考试
  8. Http缓存机制与原理
  9. java对象类型数组赋值_java声明对象数组
  10. Sql Server数据库之间如何进行异地远程连接