题目:LeetCode 004 Median of Two Sorted Arrays

There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

题意:给出两组已经排好序的数组,分为有m和n个整数,找到两个数组按顺序合并之后的中位数,使得复杂度为O(log(m+n)).

首先需明确中位数的概念,分两种情况,当合并后的数组 C[] 中个数T个,当T为奇数时,C++数组从0开始,第T/2+1个数C[T/2]为中位数,当T为偶数时,中位数为第T/2个数C[T/2-1] 和 第T/2+1个数 C[T/2]的和的一半。有下面三种思路。

思路一:利用C++最简单的思路,涉及到排序用快排sort,将两个数组合并后排序找到中位数,复杂度为O((n+m)log(n+m))。

思路二:利用已知的两个数组都有序这个特点,顺次合并排序,复杂度为O(m+n)。另外网上有一种方法也是O(m+n)的算法,用两个指针分别记录个数然后找到中位数,我尝试了一下发现边界条件太多放弃了。

我的代码如下:

class Solution {
public:double findMedianSortedArrays(vector<int>& a, vector<int>& b) {vector<int> c;    int m = a.size(), n = b.size(), i = 0, j =0;while(i < m && j < n){if(a[i] < b[j])c.push_back(a[i++]);else if(a[i] > b[j])c.push_back(b[j++]);else{c.push_back(a[i++]);c.push_back(b[j++]);}}while(i < m) c.push_back(a[i++]);while(j < n) c.push_back(b[j++]);int t = m + n;if(t&1) return c[t/2];return 0.5*(c[t/2]+c[t/2-1]);}
};

 

思路三:http://blog.csdn.net/doc_sgl/article/details/13081925

这个思路是将求中位数转化成了求两个排好序的数组的第K小的数。求中位数,即令K=T/2 或 K=T/2+1即可。

首先,两个排好序的数组A[], B[]分别有m和n个,求第k小的数。假设合并后的数组为C[],个数为m+n。

其次,要明确一个规律。将 k 分成两部分 k = pa + pb,也就是说合并后的数组的前k个数是由数组A[]的前pa个数A[0]...A[pa-1]和数组B[]的前pb个数B[0]...B[pb-1]组成。

比较数组A[]中的第pa个数和数组B[]中的第pb个数。

(1)如果A[pa-1] == B[pb-1],那么合并之后刚刚好第k=pa+pb个数即为A[pa-1]或者B[pb-1]。(递归终点1)

(2)如果A[pa-1] < B[pb-1],那么数组A中的前pa个数一定不会是数组C的第k个数。证明很简单,反证,假设A[pa-1]为第k个数,则A中有pa-1个数在C[k-1]前面,因为A[pa-1]<B[pb-1],B中之多有pb-1个数在C[k-1]前面,那么C中最多有(pa-1)+(pb-1)=pa+pb-2=k-2个数在C[k-1]前面,坐标从0开始,矛盾。

这样,我们就可以把数组A中的前pa个数删掉,求A[pa]..A[m-1] 与数组B合并之后的第k-pa小的数。

(3)同理,如果A[pa-1] > B[pb-1],那么数组B中的前pb个数一定不会是数组C的第k个数。

对于把k拆分成两部分,最简单的思路即二分,取 pa = k/2,但是有可能m < k/2,则此时取pa = m。

这样我们就将这个问题变成了一个同类的子问题,可以用递归的思路来解。递归的话,就需要考虑递归的终点:

(1)如果A或者B为空,则直接返回B[k-1]或者A[k-1];

(2)如果k为1,我们只需要返回A[0]和B[0]中的较小值;

(3)如果A[k/2-1]=B[k/2-1],返回其中一个;

思路看懂了,但是我自己的样例一直都过不了,递归还是学的不好,在一层层递归下去进入子问题时,我懂,中间调试结果也是对的,但是到达递归终点返回之后,进入上一层,我就搞不懂了。

终于过了,原因在于,子问题没有返回值。标红的三个地方出错,递归到达终点之后回返回上一层递归的函数,如果是有返回值的递归函数,加上return会在每一层递归的时候直接函数结束再次返回到上上一层的递归

由于每次删掉前面一半的元素时利用了数组首地址移动,所以写成C的代码如下:

int findKth(int a[], int m, int b[], int n, int k)
{int pa, pb;if(m > n) return findKth(b, n, a, m, k);if(m == 0) return b[k-1];if(k == 1) return a[0] < b[0] ? a[0] : b[0];pa = k/2 < m ? k/2 : m; pb = k-pa;if(a[pa-1] < b[pb-1])return findKth(a+pa, m-pa, b, n, k-pa);else if(a[pa-1] > b[pb-1])     return findKth(a, m, b+pb, n-pb, k-pb);return a[pa-1];
}double findMedianSortedArrays(int *nums1, int m, int *nums2, int n)
{int t = m+n;if(1&t) return findKth(nums1, m, nums2, n, t/2+1);return 0.5*( findKth(nums1, m, nums2, n, t/2+1) + findKth(nums1, m, nums2, n, t/2) );}

  

然后跟同学请教发现如果是C++利用vector没有办法直接利用数组首地址移动时,就需要记录vector<int>的开始位置,然后就能O(1)访问vector了。代码如下:

class Solution {
public:int findKth(vector<int> a, int m, vector<int> b, int n, int k){int lena = a.size() - m, lenb = b.size() - n;if(lena > lenb) return findKth(b, n, a, m, k);if(lena == 0) return b[n+k-1];if(k == 1) return min(a[m], b[n]);int pa = min(k/2, lena), pb = k - pa;int ida = m + pa - 1, idb = n + pb - 1;if(a[ida] < b[idb]) return findKth(a, m+pa, b, n, k-pa);else if(a[ida] > b[idb]) return findKth(a, m, b, n+pb, k-pb);return a[ida];}double findMedianSortedArrays(vector<int>& a, vector<int>& b) {int t = a.size() + b.size();if(0x1&t) return findKth(a, 0, b, 0, t/2+1);return 0.5*(findKth(a, 0, b, 0, t/2) + findKth(a, 0, b, 0, t/2+1));}
};

  

转载于:https://www.cnblogs.com/kathyrine/p/4605187.html

【LeetCode】004 Median of Two Sorted Arrays 两个排序数组合并后的中位数相关推荐

  1. LeetCode.004 Median of Two Sorted Arrays

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

  2. java打乱一组正序数字,Leetcode︱4.Median of Two Sorted Arrays寻找两个正序数组的中位数.java...

    题目 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的 中位数 . 示例 : 输入:nums1 = [1,3], nums2 = [2 ...

  3. LeetCode 4. Median of Two Sorted Arrays

    题目: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the ...

  4. LeetCode 4 Median of Two Sorted Arrays

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

  5. leetcode - 4. Median of Two Sorted Arrays

    Degree Easy ★ (*´╰╯`๓)♬ Description: There are two sorted arrays nums1 and nums2 of size m and n res ...

  6. LeetCode | 4. Median of Two Sorted Arrays(中位数)

    题目 There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the ...

  7. 【leetcode】Median of Two Sorted Arrays

    题目简述: There are two sorted arrays A and B of size m and n respectively. Find the median of the two s ...

  8. 两个排序数组合并第k或前k个最小值问题

    求最小一般用二分,求前最小一般用堆 偶尔看到一个问题,搜索了一些解法,用来存着 1.X[1..n] 和 Y[1..n]为两个数组,每个都包含n个已排好序的数.给出一个求数组X和Y中所有2n个元素的中位 ...

  9. leetcode 之Median of Two Sorted Arrays(五)

    找两个排好序的数组的中间值,实际上可以扩展为寻找第k大的数组值. 参考下面的思路,非常的清晰: 代码: double findMedianofTwoSortArrays(int A[], int B[ ...

最新文章

  1. HTML5的本地存储详解
  2. 解决Wamp 开启vhost localhost 提示 403 Forbbiden 的问题!
  3. 可以接受失败,但不选择放弃
  4. 吃CPU的openmp 程序
  5. 【云ERP】SAP S/4 HANA CLOUD 采购订单处理基本操作
  6. QEMU虚拟化加速方案 - KVM
  7. Linux高级权限管理
  8. 2021年陕西高考成绩单招查询时间,2021年陕西高考录取结果什么时候出来,查询时间一览表...
  9. python38环境变量的配置_Windows下python环境变量配置
  10. jms pub/sub模型_JMS消息传递模型:点对点和发布/订阅
  11. 第三季-第13课-无名管道通讯编程
  12. Ubuntu 离线安装软件包
  13. 329例精选matlab算法原理及源码详解——老生谈算法
  14. 用KMS激活了office2016之后为什么进入的时候还是提示需激活解决方案:
  15. 浏览器 本地html 图片不显示图片,网页图片显示不出来几种常见的解决方案
  16. 香港黄金配角吴孟达去世,80后程序员以轮播图来悼念达叔,达叔一路走好!
  17. 拔丝芋头的Java学习日记---Day11
  18. 如何求子网掩码,默认网关地址,网络地址
  19. cache的替换策略
  20. 数据分析的同比和环比以及其在excel中的应用

热门文章

  1. YOLOv3 Darknet安装编译与训练自己的数据集
  2. spring下redis开发环境搭建
  3. LeetCode 468 validate ip address(正则表达式)
  4. 国外程序员整理的 C++ 资源大全
  5. zookeeper代码浅析
  6. 为何要fork()两次来避免产生僵尸进程?
  7. 几种P2P流媒体开源项目介绍
  8. Python学习之==数组(一)
  9. 【OO学习】OO第四单元作业总结及OO课程总结
  10. MYSQL、SQL在LIKE里传的参数没有赋进去的原因