Median of Two Sorted Arrays-LeetCode
2014-09-15 14:02
225 查看
题目:
There are two sorted arrays A and B of size m and n respectively.Find the Median of two sorted arrays.The overall run time complexity should be O(log(m+n)).
题目分析:
当我第一眼看见这题目时,就想到采用归并排序的方式,在两个数组上设立两个指针从头开始逐一比较。直到找到对应的元素为止。下面是自己开始写的代码:
但是运行之后就发现出现了错误,折腾了很久也没有想明白。后面在网上找资料,才明白自己犯了一个最基本的错误,没有理解Median的含义。当Array的个数是奇数时,Median的值是最中间的一个。当它是偶数时,Median的值是n/2和n/2+1上的值的平均数。
网上的解法普遍都是一样的,看了之后发现这种解法确实很巧妙,貌似是某年考研的算法题,先记录下来。
解题思路:
该方法的核心是将原问题转变成一个寻找第k小的数问题(假设两个原序列升序排列),这样中位数实际上是第(m+n)/2小的数(暂不考虑偶数情形).所以只要解决了第k小的数,原问题就得以解决。
首先假设数组A和B的元素个数都大于k/2,我们比较A[k/2-1]和B[k/2-1]两个元素,分别代表A和B数组的第k个元素。如果A[k/2-1]<B[k/2-1],这表示A[0]到A[k/2-1]的元素都在A和B合并之后的前k个元素中。也就是说,A[k/2-1]不可能大于两数组合并之后的第k小值,所以我们可以将其抛弃。(注意:这是该算法最核心的地方)。
反证法:
假设A[k/2-1]大于合并之后的第k小值,我们不妨假定为第(k+1)小值。由于A[k/2-1]小于B[k/2-1],所以B[k/2-1]至少是第(k+2)小值。但实际上,在A中至多存在k/2-1个元素小于A[k/2-1],B中至多存在k/2-1个元素A[k/2-1],所以小于A[k/2-1]的元素个数至多有k/2+k/2-2,小于k,这与A[k/2-1]是k+1的数矛盾。
当A[k/2-1]>B[k/2-1]时也类似。
当A[k/2-1]==B[k/2-1]时,则我们已经找到第k的元素,也就是这个相等的元素。将其记为m,由于A和B中分别有k/2-1个元素小于m,所以m即是第k小的数。
因此总结起来就是:
如果A或者B为空,则直接返回B[k-1]或者A[k-1]。
如果k为1,我们只需要返回A[0]和B[0]中的较小值。
如果A[k/2-1]=B[k/2-1],返回其中一个。
代码如下:
There are two sorted arrays A and B of size m and n respectively.Find the Median of 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) { double result,right; int num=(n+m+1)/2; int i=0,j=0,cnt=0; while(i!=m && j!=n){ if(A[i]<=B[j]){ result=A[i]; i++; cnt++; } else{ result=B[j]; j++; cnt++; } if(cnt==num) { flag=true; break; } } while(i!=m){ if(cnt==num) break; else{ result=A[i]; i++; cnt++; } } while(j!=n){ if(cnt==num) break; else{ result=B[j]; j++; cnt++; } } return result; }
但是运行之后就发现出现了错误,折腾了很久也没有想明白。后面在网上找资料,才明白自己犯了一个最基本的错误,没有理解Median的含义。当Array的个数是奇数时,Median的值是最中间的一个。当它是偶数时,Median的值是n/2和n/2+1上的值的平均数。
网上的解法普遍都是一样的,看了之后发现这种解法确实很巧妙,貌似是某年考研的算法题,先记录下来。
解题思路:
该方法的核心是将原问题转变成一个寻找第k小的数问题(假设两个原序列升序排列),这样中位数实际上是第(m+n)/2小的数(暂不考虑偶数情形).所以只要解决了第k小的数,原问题就得以解决。
首先假设数组A和B的元素个数都大于k/2,我们比较A[k/2-1]和B[k/2-1]两个元素,分别代表A和B数组的第k个元素。如果A[k/2-1]<B[k/2-1],这表示A[0]到A[k/2-1]的元素都在A和B合并之后的前k个元素中。也就是说,A[k/2-1]不可能大于两数组合并之后的第k小值,所以我们可以将其抛弃。(注意:这是该算法最核心的地方)。
反证法:
假设A[k/2-1]大于合并之后的第k小值,我们不妨假定为第(k+1)小值。由于A[k/2-1]小于B[k/2-1],所以B[k/2-1]至少是第(k+2)小值。但实际上,在A中至多存在k/2-1个元素小于A[k/2-1],B中至多存在k/2-1个元素A[k/2-1],所以小于A[k/2-1]的元素个数至多有k/2+k/2-2,小于k,这与A[k/2-1]是k+1的数矛盾。
当A[k/2-1]>B[k/2-1]时也类似。
当A[k/2-1]==B[k/2-1]时,则我们已经找到第k的元素,也就是这个相等的元素。将其记为m,由于A和B中分别有k/2-1个元素小于m,所以m即是第k小的数。
因此总结起来就是:
如果A或者B为空,则直接返回B[k-1]或者A[k-1]。
如果k为1,我们只需要返回A[0]和B[0]中的较小值。
如果A[k/2-1]=B[k/2-1],返回其中一个。
代码如下:
public:{ dobule findKth(int A[],int m,int B[],int n,int k){ //m is equal or smaller than n if(m<n) return findKth(B,n,A,m,k); if(m==0) return B[k-1]; if(k==1) return min(A[0],B[0]); int pa=min(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); else return A[pa-1]; } dobule findMedianSortedArrays(int A[],int m,int B[],int n){ int k=m+n; if(k & 0x1){ return findKth(A,m,B,n,k/2+1); } else{ return (findKth(A,m,B,n,k/2)+findKth(A,m,B,n,k/2+1))/2; } } };
相关文章推荐
- leetcode Median of Two Sorted Arrays
- [leetcode]Median of Two Sorted Arrays
- leetcode 26: Median of Two Sorted Arrays
- LeetCode: Median of Two Sorted Arrays
- LeetCode题目笔记(三) -- Median of Two Sorted Arrays
- LeetCode 4 - Median of Two Sorted Arrays
- [leetcode] Median of Two Sorted Arrays
- [LeetCode] Median of Two Sorted Arrays 解题报告
- LeetCode: Median of Two Sorted Arrays
- LeetCode刷题笔录 Median Of Two Sorted Arrays
- LeetCode Online Judge 题目C# 练习 - Median of Two Sorted Arrays
- leetCode_Median of Two Sorted Arrays
- LeetCode: Median of Two Sorted Arrays
- leetcode 26: Median of Two Sorted Arrays
- LeetCode Median of Two Sorted Arrays
- LeetCode-Median of Two Sorted Arrays
- Median of Two Sorted Arrays-----LeetCode
- [LeetCode题解004]Median of Two Sorted Arrays
- LeetCode —— Median of Two Sorted Arrays
- leetcode-004:Median of Two Sorted Arrays