文章目录

  • 1. 题目
  • 2. 解题
    • 2.1 合并数组
    • 2.2 优化2.1解法,双指针
    • 2.3 二分法(找第k个数)
    • 2.4 切分法

1. 题目

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为O(log(m+n))O(log(m + n))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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

2.1 合并数组

  • 合并两个数组,再取中位数
  • 时间和空间复杂度均为 O(m+n)
class Solution {public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int n1 = nums1.size(), n2 = nums2.size(), len;len = n1 + n2;vector<int> nv(len);int i = 0, j = 0, k = 0;while(i < n1 && j < n2){if(nums1[i] < nums2[j])nv[k++] = nums1[i++];elsenv[k++] = nums2[j++];}if(i == n1){while(j < n2)nv[k++] = nums2[j++];}else{while(i < n1)nv[k++] = nums1[i++];}if(len%2)return nv[len/2];return (nv[len/2]+nv[len/2-1])/2.0;}
};

2.2 优化2.1解法,双指针

  • 不合并两个数组,设置双指针在两个数组上
  • 比较大小,分别移动各自的指针,遍历到中间的计数停止
  • 时间复杂度 O(m+n),空间复杂度 O(1)
class Solution {public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int n1 = nums1.size(), n2 = nums2.size(), len;len = n1 + n2;vector<int> nv(len);int i = 0, j = 0, k, left = -1, right = -1;for(k = 0; k <= len/2; ++k){left = right;if(i < n1 && (j >= n2 || nums1[i] < nums2[j]))right = nums1[i++];elseright = nums2[j++];}if(len%2)return right;return (left+right)/2.0;        }
};

2.3 二分法(找第k个数)

参考链接,解法3



class Solution {public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int n1 = nums1.size(), n2 = nums2.size(), len, kth;len = n1 + n2;kth = (len+1)/2;if(len%2)return findKth(nums1,0,n1-1,nums2,0,n2-1,kth);return (findKth(nums1,0,n1-1,nums2,0,n2-1,kth)+findKth(nums1,0,n1-1,nums2,0,n2-1,kth+1))/2.0;      }int findKth(vector<int>& nums1, int s1, int e1, vector<int>& nums2, int s2, int e2, int kth){int len1 = e1-s1+1;int len2 = e2-s2+1;if(len1 > len2) //确保传进来的参数len1是较短的数组(它先空)return findKth(nums2,s2,e2,nums1,s1,e1,kth);if(len1 == 0)return nums2[s2+kth-1];//一个为空,直接找到答案if(kth == 1)return min(nums1[s1],nums2[s2]);int i = s1+min(len1,kth/2)-1;//min使得指针不会越界int j = s2+min(len2,kth/2)-1;if(nums1[i] > nums2[j])//舍去nums2前面的return findKth(nums1,s1,e1,nums2,j+1,e2,kth-(j-s2+1));else//舍去nums1前面的return findKth(nums1,i+1,e1,nums2,s2,e2,kth-(i-s1+1));}
};

O(lg(m+n))O(lg(m+n))O(lg(m+n))时间复杂度,尾递归,无需堆栈,空间复杂度 O(1)O(1)O(1)

2.4 切分法

  • 放了方便处理,确保A数组长度较短
  • 初始状态下mid1取数组1的中间,mid1,mid2左半边的总个数 == 右半边 或者 比右半边少1
  • 对mid1进行二分查找,相应的mid2会随动(mid2=allHalf−mid1mid2 = allHalf - mid1mid2=allHalf−mid1)
  • 如果 lmax1<=rmin2,andlmax2<=rmin1lmax1 <= rmin2 ,\quad and \quad lmax2 <= rmin1lmax1<=rmin2,andlmax2<=rmin1 , 成功找到分界线
  • 则 Lmax=max(lmax1,lmax2))Lmax = max(lmax1,lmax2))Lmax=max(lmax1,lmax2)), Rmin=min(rmin1,rmin2)Rmin = min(rmin1, rmin2)Rmin=min(rmin1,rmin2),总个数为奇数返回RminRminRmin, 偶数返回(Lmax+Rmin)/2.0(Lmax+Rmin)/2.0(Lmax+Rmin)/2.0
class Solution {public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int n1 = nums1.size(), n2 = nums2.size();if(n1 > n2)//确保n1是较短的数组return findMedianSortedArrays(nums2, nums1);int left = 0, right = n1, allHalf = (n1+n2)/2, mid1, mid2;int lmax1, rmin1, lmax2, rmin2;while(left <= right){mid1 = left+((right-left)>>1);mid2 = allHalf - mid1;lmax1 = (mid1-1 >= 0) ? nums1[mid1-1] : INT_MIN;rmin1 = (mid1 < n1) ? nums1[mid1] : INT_MAX;lmax2 = (mid2-1 >= 0) ? nums2[mid2-1] : INT_MIN;rmin2 = (mid2 < n2) ? nums2[mid2] : INT_MAX;//在边界处,认为没有元素,设置成最大或者最小,保证下面关系式成立if(lmax1 > rmin2)right = mid1-1;else if(lmax2 > rmin1)left = mid1+1;else{left = right = mid1;break;}}int i = left, j = allHalf-left;int l = max(i-1 >= 0 ? nums1[i-1] : INT_MIN,j-1 >= 0 ? nums2[j-1] : INT_MIN);int r = min(i < n1 ? nums1[i] : INT_MAX,j < n2 ? nums2[j] : INT_MAX);if((n1+n2)%2 == 1)return r;return (l+r)/2.0;}
};

LeetCode 4. 寻找两个有序数组的中位数(二分查找,难)相关推荐

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

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

  2. leetcode 4. 寻找两个有序数组的中位数,c语言

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

  3. [leetcode] 4 寻找两个有序数组的中位数(二分+递归查找第K小数)(重要)

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

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

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

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

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

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

    1 题目 给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的中位数. 进阶:设计一个时间复杂度为 O(log (m+n)) 的算法. 2 解 ...

  7. [leetcode] 4. 寻找两个有序数组的中位数

    官方题解:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xun-zhao-liang-ge-you-xu- ...

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

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

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

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

最新文章

  1. 启动子级时出错_减速机安装与使用时需注意的八个要点,细节很重要!
  2. 移动互联时代:儿童教育重在内容和应用
  3. Java volatile关键字原理解剖
  4. 洛谷-P3203 弹飞绵羊 分块
  5. Java面试知识点:网络编程
  6. 高门槛的动作捕捉技术,真的会成为VR行业灾难的缔造者吗?
  7. 【转】QDockWidget 停靠窗口和工具栏
  8. 代码审查(咳咳......又降温了啊....!!!!)
  9. 任务管理平台_“平房区教师培训学分管理平台启用暨任务部署培训会议”
  10. JavaWeb初级篇-HttpPost使用教程
  11. CRM各行业解决方案
  12. U盘拷贝大文件提示文件过大无法拷贝怎么解决
  13. hdu2037-简单dp
  14. Pytorch 模型 查看网络参数的梯度以及参数更新是否正确,优化器学习率设置固定的学习率,分层设置学习率
  15. python数据分析 - T检验与F检验:二组数据那个更好?(一)
  16. win11关闭防火墙
  17. App开发者必备的运营、原型、UI设计工具整理
  18. 《2020 数字中国指数报告》重磅发布,汤道生宣布将投入 100 亿用于开发中小企业专属 SaaS 产品及方案...
  19. 全球与中国医疗计费软件市场深度研究分析报告
  20. 【论文阅读】【ViT系列】ViT:一张图片用于大规模图像识别的Transformers(手动翻译)

热门文章

  1. django html显示xml,如何将HTML与Django集成?
  2. JAVA开发工具下载
  3. [New Portal]Windows Azure Virtual Machine (17) Virtual Machine成本分析
  4. Spring系列(六) Spring Web MVC 应用构建分析
  5. BZOJ 4259: 残缺的字符串 [FFT]
  6. 在XML文件中定义动画(1)
  7. flash和js通讯的伪沙箱安全错误
  8. Lucene.Net:关于索引的一些补充说明和总结
  9. boost_1_48_0 在VS2008下的安装 Boost.Asio安装
  10. 如何让new操作符只构造,不申请内存