LeetCode2:Median of Two Sorted Arrays
2014-04-29 10:26
302 查看
题目:
There are two sorted arrays A and B 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为偶数的话,应为中间两数之和除2,但时间复杂度不符合题目要求,还一种方法就是利用归并思想,因为两数组为排序数组,对两数组进行归并,当已归并个数为(m+n)/2时,即求得中间数,不用继续归并了,不过这种方式时间复杂度也不符合要求。那有没其他更快的方法呢。
这里要说的就是利用二分查找的方式,当要在排序数组中查找某个元素时,我们就应该朝二分法查找思考。二分法正是利用已排序数组这一特性快速查找。该方法的核心是将原问题转变成一个寻找第k小数的问题(假设两个原序列升序排列),这样中位数实际上是第(m+n)/2小的数。所以只要解决了第k小数的问题,原问题也得以解决。首先假设数组A和B的元素个数都大于k/2,我们比较A[k/2-1]和B[k/2-1]两个元素,这两个元素分别表示A的第k/2小的元素和B的第k/2小的元素。这两个元素比较共有三种情况:>、<和=。如果A[k/2-1]<B[k/2-1],这表示A[0]到A[k/2-1]的元素都在A和B合并之后的前k小的元素中。换句话说,A[k/2-1]不可能大于两数组合并之后的第k小值,所以我们可以将其抛弃。
实现代码:
There are two sorted arrays A and B 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为偶数的话,应为中间两数之和除2,但时间复杂度不符合题目要求,还一种方法就是利用归并思想,因为两数组为排序数组,对两数组进行归并,当已归并个数为(m+n)/2时,即求得中间数,不用继续归并了,不过这种方式时间复杂度也不符合要求。那有没其他更快的方法呢。
这里要说的就是利用二分查找的方式,当要在排序数组中查找某个元素时,我们就应该朝二分法查找思考。二分法正是利用已排序数组这一特性快速查找。该方法的核心是将原问题转变成一个寻找第k小数的问题(假设两个原序列升序排列),这样中位数实际上是第(m+n)/2小的数。所以只要解决了第k小数的问题,原问题也得以解决。首先假设数组A和B的元素个数都大于k/2,我们比较A[k/2-1]和B[k/2-1]两个元素,这两个元素分别表示A的第k/2小的元素和B的第k/2小的元素。这两个元素比较共有三种情况:>、<和=。如果A[k/2-1]<B[k/2-1],这表示A[0]到A[k/2-1]的元素都在A和B合并之后的前k小的元素中。换句话说,A[k/2-1]不可能大于两数组合并之后的第k小值,所以我们可以将其抛弃。
实现代码:
#include <iostream> using namespace std; /** There are two sorted arrays A and B 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)). */ class Solution { public: double findMedianSortedArrays(int A[], int m, int B[], int n) { int k = (m + n) / 2; if((m + n) & 0x1)//奇数 return findKthNumber(A, m, B, n, k + 1); return (findKthNumber(A, m, B, n, k) + findKthNumber(A, m, B, n, k+1)) / 2; } double findKthNumber(int A[], int m, int B[], int n, int k) { if(m > n) return findKthNumber(B, n, A, m, k);//这里始终假设m<n if(m == 0) return B[k-1]; if(n == 0) return A[k-1]; if(k == 1) return A[0] < B[0] ? A[0] : B[0]; int ak = min(k / 2, m); int bk = k - ak; if(A[ak-1] < B[bk-1]) return findKthNumber(A+ak, m-ak, B, n, k-ak); else return findKthNumber(A, m, B+bk, n-bk, k-bk); } }; int main(void) { int A[] = {1,5,7,9,14,15}; int B[] = {3,6,10,13,18,20}; Solution s; double res = s.findMedianSortedArrays(A, 6, B, 6); cout<<res<<endl; return 0; }
相关文章推荐
- 个人电脑搭建服务器
- c/c++ 访问 hdfs
- FZU 2169 shadow
- HDU-1074 Doing Homework 状态压缩DP
- xml 命名空间
- java 内部类
- Create shortcuts in Linux (symbolic links)
- AIX写shell脚本的for循环
- jQuery Mobile 页面事件
- listview 之 divider
- 监控线上系统异常日志
- Jtable简单的封装使用
- Asteroids 题解
- 一位码农的几点思考
- android 获取View的坐标
- perl中的多行匹配问题
- nagios系统监控部署
- class-1
- 【博客分享】优秀的有趣的博客
- scp 在脚本中使用输入密码的解决方法