Median of Two Sorted Arrays
来源:互联网 发布:算法竞赛宝典 百科 编辑:程序博客网 时间:2024/06/04 19:53
/*Description:There are two sorted arrays A and B of size m and n respectively. Find the median of the two sortedarrays. The overall run time complexity should be O(log(m + n)).给定两个已经排序好的数组,找到两者的中值。*//*Parse:首先把这个问题可以化成一般形式,寻找两个已序数组中所有元素的第k大元素。1、最直接的解法,合并两个数组然后求第k大的元素。但是我们仅仅需要第k大的元素,不需要排序这么“昂贵”的操作。2、可以用一个计数器,记录当前已经找到第m大的元素了。同时使用两个指针pA和pB,分别指向A和B数组的第一个元素,如数组A当前元素小,则pA++,同时m++;如数组B当前元素小,则pB++,同时m++;最终当m等于k时,得到答案。但是当k接近m+n时,与第一种解法复杂度相同。3、假设A和B元素个数都大于k/2,将A的第k/2个元素和B的第k/2个元素比较,有三种情况(为了简化先假设k为偶数,结论对奇数也成立)A[k/2-1] == B[k/2-1]A[k/2-1] > B[k/2-1]A[k/2-1] < B[k/2-1]当A[k/2-1] < B[k/2-1]时,A[k/2-1]不大于A与B合并后的第k大元素。可以删除A数组的这k/2个元素。同理,A[k/2-1] > B[k/2-1]时,可以删除B数组的这k/2个元素。当A[k/2-1] == B[k/2-1]时,说明找到了第k大的元素,直接返回A[k/2-1]或B[k/2-1]。*/// LeetCode, Median of Two Sorted Arrays// 时间复杂度 O(log(m+n)) 空间复杂度 O(log(m+n))
#include <vector>#include <iostream>#include <algorithm>using namespace std;int find_kth(vector<int>::const_iterator A, int m, vector<int>::const_iterator B, int n, int k){ if (m > n) return find_kth(B, n, A, m, k); if (m == 0) return *(B + k - 1); if (k == 1) return min(*A, *B); int ia = min(k / 2, m), ib = k - ia; if (*(A + ia - 1) < *(B + ib - 1)) return find_kth(A + ia, m - ia, B, n, k - ia); else if (*(A + ia - 1) > *(B + ib - 1)) return find_kth(A, m, B + ib, n - ib, k - ib); else return A[ia - 1];}double findMedianSortedArrays(const vector<int>& A, const vector<int>& B){ const int m = A.size(); const int n = B.size(); int total = m + n; if (total & 0x1) //奇偶判断 return find_kth(A.begin(), m, B.begin(), n, total / 2 + 1); else return (find_kth(A.begin(), m, B.begin(), n, total / 2) + find_kth(A.begin(), m, B.begin(), n, total / 2 + 1)) / 2.0;}int main(){ vector<int> A = {1,2,3,5}, B = {2,4,5,6}; cout << findMedianSortedArrays(A, B) << endl; return 0;}
/*Description:There are two sorted arrays A and B of size m and n respectively. Find the median of the two sortedarrays. The overall run time complexity should be O(log(m + n)).给定两个已经排序好的数组,找到两者的中值。*//*Parse: 这是一道非常经典的题,这题更通用的形式是,给定两个已排序好的数组,找到两者所有元素中第k大的元素。O(m+n)的解法比较直观,直接merge两个数组,然后求第k大的元素。 不过我们仅仅需要第k大的元素,是不需要“排序”这么昂贵的操作的。可以用一个计数器,记录记录当前已经找到第m大的元素了。同时使用两个指针pA和pB,分别指向A和B数组的第一个元素,使用类似于merge sort 的原理。如果数组A当前元素小,则pA++,同时m++;如数组B当前元素小,则pB++,同时m++;最终当m等于k时,得到答案,O(k)时间,O(1)空间。 但是当k接近m+n时,这个方法还是O(m+n)的。有没有更好的方案呢? 我们可以考虑从k入手。如果我们每次都能够删除一个一定在第k大元素之前的元素,那么我们就只需要进行k次。但是如果每次我们都删除一半呢?由于A和B都是有序的,我们应该充分利用这里面的信息,类似于二分查找,也是充分利用了“有序”。 假设A和B的元素个数都大于k/2,我们将A的第k/2个元素(即A[k/2-1])和B的第k/2个元素(即B[k/2-1])比较,有以下三种情况(为了简化这里,先假设k为偶数,所得结论对于k是奇数也成立): A[k/2-1] == B[k/2-1] A[k/2-1] > B[k/2-1] A[k/2-1] < B[k/2-1] 1).当A[k/2-1] < B[k/2-1]时,意味着A[0]到A[k/2-1]的肯定在A + B (A并B)的top k 元素的范围内。换句话说,A[k/2-1]不可能大于A + B的第k大元素。因此,我们可以放心的删除A数组的这k/2个元素。 2).同理,当A[k/2-1] > B[k/2-1]时,可以删除B数组的k/2个元素。 3).当A[k/2-1] == B[k/2-1]时,说明找到了第k大的元素,直接返回A[k/2-1]或B[k/2-1]即可。 因此,我们可以写一个递归函数,那么函数什么时候应该终止呢? 当A或B是空时,直接返回B[k-1]或A[k-1]; 当k=1时,返回min(A[0],B[0]); 当A[K/2-1] == B[k/2-1]时,返回A[k/2-1]或B[k/2-1]*/// LeetCode, Median of Two Sorted Arrays// 时间复杂度 O(log(m+n)) 空间复杂度 O(log(m+n))class Solution { public: double findMedianSortedArrays(const vector<int>& A, const vector<int>& B) { const int m = A.size(); const int n = B.size(); int total = m + n; if (total & 0x1) return find_kth(A.begin(), m, B.begin(), n, total / 2 + 1); else return (find_kth(A.begin(), m, B.begin(), n, total / 2) + find_kth(A.begin(), m, B.begin(), n, total / 2 + 1)) / 2.0; } private: static int find_kth(std::vector<int>::const_iterator A, int m, std::vector<int>::const_iterator B, int n, int k) { //always assume that m is equal or smaller than n if (m > n) return find_kth(B, n, A, m, k); if (m == 0) return *(B + k - 1); if (k == 1) return min(*A, *B); //divide k into two parts int ia = min(k / 2, m), ib = k - ia; if (*(A + ia - 1) < *(B + ib - 1)) return find_kth(A + ia, m - ia, B, n, k - ia); else if (*(A + ia - 1) > *(B + ib - 1)) return find_kth(A, m, B + ib, n - ib, k - ib); else return A[ia - 1]; }};
0 0
- Median of Two Sorted Arrays
- Median of Two Sorted Arrays
- Median of Two Sorted Arrays
- Median of two sorted arrays
- Median of Two Sorted Arrays
- Median of Two Sorted Arrays
- Median of Two Sorted Arrays
- Median of Two Sorted Arrays
- Median of Two Sorted Arrays
- Median of Two Sorted Arrays
- median-of-two-sorted-arrays
- Median of Two Sorted Arrays
- Median of Two Sorted Arrays
- Median of Two Sorted Arrays
- Median of Two Sorted Arrays
- Median of Two Sorted Arrays
- Median of Two Sorted Arrays
- Median of Two Sorted Arrays
- 上传本地代码到github
- solr5.5+tomcat8+jdk1.8配置
- AtCoder:AtCoder Group Contest(思维)
- mysql非法关机导致 错误 1067:进程意外终止
- Find a multiple (POJ
- Median of Two Sorted Arrays
- 杭电5305 Friends 搜索
- c++之A a和A *a=new A()
- LeetCode (Insert Interval)
- 归并排序
- 常用的创建线程池的方法
- jQuery语法,是一种很接近于java的语法,即 对象.function()
- 使用fastdfs_client的storage.upload_file方法上传图片抛FileNotFound异常
- poj 1061 扩展欧几里德