【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 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 两个排序数组合并后的中位数相关推荐
- 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 ...
- java打乱一组正序数字,Leetcode︱4.Median of Two Sorted Arrays寻找两个正序数组的中位数.java...
题目 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的 中位数 . 示例 : 输入:nums1 = [1,3], nums2 = [2 ...
- 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 ...
- 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 ...
- leetcode - 4. Median of Two Sorted Arrays
Degree Easy ★ (*´╰╯`๓)♬ Description: There are two sorted arrays nums1 and nums2 of size m and n res ...
- 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 ...
- 【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 ...
- 两个排序数组合并第k或前k个最小值问题
求最小一般用二分,求前最小一般用堆 偶尔看到一个问题,搜索了一些解法,用来存着 1.X[1..n] 和 Y[1..n]为两个数组,每个都包含n个已排好序的数.给出一个求数组X和Y中所有2n个元素的中位 ...
- leetcode 之Median of Two Sorted Arrays(五)
找两个排好序的数组的中间值,实际上可以扩展为寻找第k大的数组值. 参考下面的思路,非常的清晰: 代码: double findMedianofTwoSortArrays(int A[], int B[ ...
最新文章
- HTML5的本地存储详解
- 解决Wamp 开启vhost localhost 提示 403 Forbbiden 的问题!
- 可以接受失败,但不选择放弃
- 吃CPU的openmp 程序
- 【云ERP】SAP S/4 HANA CLOUD 采购订单处理基本操作
- QEMU虚拟化加速方案 - KVM
- Linux高级权限管理
- 2021年陕西高考成绩单招查询时间,2021年陕西高考录取结果什么时候出来,查询时间一览表...
- python38环境变量的配置_Windows下python环境变量配置
- jms pub/sub模型_JMS消息传递模型:点对点和发布/订阅
- 第三季-第13课-无名管道通讯编程
- Ubuntu 离线安装软件包
- 329例精选matlab算法原理及源码详解——老生谈算法
- 用KMS激活了office2016之后为什么进入的时候还是提示需激活解决方案:
- 浏览器 本地html 图片不显示图片,网页图片显示不出来几种常见的解决方案
- 香港黄金配角吴孟达去世,80后程序员以轮播图来悼念达叔,达叔一路走好!
- 拔丝芋头的Java学习日记---Day11
- 如何求子网掩码,默认网关地址,网络地址
- cache的替换策略
- 数据分析的同比和环比以及其在excel中的应用