原题链接Median of Two Sorted Arrays

意思是给定两个有序序列,找到合并之后的中位数,要求复杂度O(log(m+n))。扩展方面,找到合并之后第K小的数,因为中位数也符合第K小范畴,所以直接按照后者解题即可


不考虑复杂度的情况下,首先想到的方法是一次从两个数组中选取较小的那个,直到选取第k个,此种方法复杂度在O(k),代码如下

class Solution {
public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int lhs_idx = 0;int rhs_idx = 0;/* 奇数偶数时中位数计算方法不同 */int total = nums1.size() + nums2.size();if(total % 2 == 0){return (findKth(nums1, nums2, total / 2) + findKth(nums1, nums2, total / 2 + 1)) / 2.0;}else{return findKth(nums1, nums2, total / 2 + 1) / 1.0;}}int findKth(vector<int>& nums1, vector<int>& nums2, int k){int ans = 0;int lhs_idx = 0;int rhs_idx = 0;/* 复杂度体现处,遍历k次,所以为O(k) */while(k--){/* 需要考虑边界情况 */if(lhs_idx >= nums1.size() && rhs_idx < nums2.size())ans = nums2[rhs_idx++];else if(lhs_idx < nums1.size() && rhs_idx >= nums2.size())ans = nums1[lhs_idx++];else if(lhs_idx >= nums1.size() && rhs_idx >= nums2.size())return -1;else if(nums1[lhs_idx] < nums2[rhs_idx])ans = nums1[lhs_idx++];elseans = nums2[rhs_idx++];           }return ans;}};

接下来想办法达到O(log(m+n)),涉及到log通常会考虑二分法,所以优化需要在findKth()函数中采用二分法计算。下面把nums1看成数组A,nums2看成数组B,A的大小为m,B的为n
既然需要找到第K小的数,那么首先考虑A的第k/2个元素和B的第k/2个元素。这么考虑是因为

  • 既然采用二分法,那么使用时通过二分就一定可以把结果的范围缩小

具体说明,
如果A[k/2] > B[k/2],说明B的前k/2个元素在合并A,B之后的前k个位置

  • 因为A[k/2]] > B[k/2],那么假设A[i] == B[k/2],i一定小于k/2,显然此时A的前i个,B的前k/2个元素一定都是组成合并之后前k小元素的成员,所以B的前k/2个元素一定都是前k个元素的成员
  • 所以此时就已经找到了k/2个元素了,只需再找k/2个最小的元素即可,而这些元素都在B的[k/2, n)和A中,很明显可以利用递归,此时k改为k/2

如果A[k/2] <= B[k/2],在A的[k/2,m)和B中查找剩下的k/2个元素,原理同上

代码如下

class Solution {
public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int m = nums1.size();int n = nums2.size();int total = m + n;if(total % 2 == 0){return (findKth(nums1, nums2, total / 2) + findKth(nums1, nums2, total / 2 + 1)) / 2.0;}else{return findKth(nums1, nums2, total / 2 + 1) / 1.0;}}int findKth(vector<int> A, vector<int> B, int k){/* 总是让A的大小小于B */if(A.size() > B.size())return findKth(B, A, k);if(A.size() == 0)return B[k - 1];if(k == 1)return std::min(A[0], B[0]);int m = A.size();int n = B.size();/* 如果大小不足k/2,取自身大小 *//* 因为有这种情况,后面不一定是k/2,所以递归调用时是k - j/k - i */int i = std::min(m, k / 2);int j = std::min(n, k / 2);if(A[i - 1] > B[j - 1]){return findKth(A, std::vector<int>(B.begin() + j, B.end()), k - j);}else{return findKth(std::vector<int>(A.begin() + i, A.end()), B, k - i);}}
};

准确说这种方法没有达到O(log(m+n)),但是更具通用性,可以计算不仅仅是中位数,还可以计算第k小元素,效率相对更高。

不过就本题而言,每次二分AB中间的位置,根据大小关系抛弃小方的左端以及大方同样长度的右端,以达到最后的结果,但是没有什么通用性,只可以计算中位数

每天一道LeetCode-----两个有序数组合并后的第K个数相关推荐

  1. ZZULIOJ 1124: 两个有序数组合并

    两个有序数组合并 题目描述 已知数组a中有m个按升序序排列的元素,数组b中有n个降序排列的元素,编程将a与b中的所有元素按降序存入数组c中. 输入 输入有两行,第一行首先是一个正整数m,然后是m个整数 ...

  2. 用c语言编写两个有序数组合并,C++实现两个有序数组的合并

    本文实例为大家分享了C++实现两个有序数组合并的具体代码,供大家参考,具体内容如下 剑指offer面试题5延展题: 问题:有两个排序的数组A1和A2,内存在A1的末尾有足够多的空间容纳A2.请实现一个 ...

  3. 【LeetCode】004 Median of Two Sorted Arrays 两个排序数组合并后的中位数

    题目:LeetCode 004 Median of Two Sorted Arrays There are two sorted arrays nums1 and nums2 of size m an ...

  4. 将两个有序数组合并成一个有序数组

    将两个有序数组按从小到大顺序合并成一个数组. #include<iostream> using namespace std; int main() {int a[5]={1,5,6,8,9 ...

  5. 两种思路将Python中两个有序数组合并为一个有序数组

    第一种思路: 把两个数组合为一个数组然后再排序,问题又回归到冒泡和快排了,没有用到两个数组的有序性. 第二种思路: 循环比较两个有序数组头位元素的大小,并把头元素放到新数组中,从老数组中删掉,直到其中 ...

  6. 求两个有序数组的中位数或者第k小元素

    问题:两个已经排好序的数组,找出两个数组合并后的中位数(如果两个数组的元素数目是偶数,返回上中位数). 设两个数组分别是vec1和vec2,元素数目分别是n1.n2. 算法1:最简单的办法就是把两个数 ...

  7. 两个有序数组的中位数(第k大的数)

    问题:两个已经排好序的数组,找出两个数组合并后的中位数(如果两个数组的元素数目是偶数,返回上中位数). 感觉这种题目挺难的,尤其是将算法完全写对.因为当初自己微软面试的时候遇到了,但是没有想出来思路. ...

  8. 合并两个有序链表,合并后依然有序

    合并两个有序链表合并之后还是有序的,首先这两个链表是需要是有序的,也就是说这两个链表已经排好序了,才能进行合并.但是昨天也写过冒泡排序的程序了,如果让你合并两个不是有序的链表合并之后有序,那可以先将两 ...

  9. 将两个有序数组合并到一起

    给出两个有序的整数数组A和B,请将数组B合并到数组A中,变成一个有序的数组 注意: 可以假设A数组有足够的空间存放B数组的元素,A和B中初始的元素数目分别为m和n 暴力:t((n+m)*log(m+n ...

最新文章

  1. 有光照就能上网 0.2秒即可下载一部高清电影
  2. python shell背景颜色改变_科学网—Python Shell Background Color - 李旭的博文
  3. TweetBot TabBar
  4. SQL 表之间的更新
  5. AtCoder Beginner Contest 129
  6. javascript中变量的判断
  7. mysql中一些简单但是新手容易犯的错误
  8. HelloWorld程序的代码编写
  9. spi 协议驱动设计
  10. ffmpy3与ffmpeg的简单使用
  11. MQTT工作笔记0006---CONNECT控制报文3
  12. cookie和session理解
  13. java的Date.getTime()转换成C#的Datetime.ticks
  14. windows 花式装系统
  15. impala常用函数大全(超详细哦)
  16. CSS DIV 折角的代码
  17. hdoopHA的文件配置和安装hadoop和安装zookeeper
  18. 短视频矩阵系统H5形式视频分享如何开发?
  19. layui.css地址,layui+高德获取经纬度(可点击更换位置)
  20. python numpy.arry, pytorch.Tensor及原生list相互转换

热门文章

  1. 计算机网络实验类型有哪些,北航研究生计算机网络实验_实验三 网络层实验
  2. mysql insert执行过程_MySQL · 源码分析 · 一条insert语句的执行过程
  3. HDU1172猜数字 [模拟]
  4. livecd制作 centos
  5. 2.vue 安装教程
  6. 关于EGE图形库在CodeBlocks下的配置
  7. 为了使界面组件更圆滑,Swing,且跨系统
  8. 01.WPF中制作无边框窗体
  9. Data Storage(数据存储)之内部储存(Internal Storage)
  10. 类实现Java模板方法模式中的HookMethod实现