Leetcode--Median of Two Sorted Arrays
2015-03-07 09:27
288 查看
题目:
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)).
初看到这一题的思路是按照插入排序的思路将两个已经排好序的数组合并到一起,然后按照直接在新合并的数组中找到中间位置的数,这样的算法时间复杂度为O(m+n),这样的代码也可以通过,因为Leetcode的测试样例目前还不能检测log(n)和O(n)的差异,但是看这一题目要求是要求时间复杂度为log(m+n)。初看这题很简单,其实不然,后来在Leetcode的讨论板上看到了解决方法。其实这一题就是寻找两个数组的第k小位置的数,假定A和B都是按照升序排列的(这个不影响问题的分析),如果A[k/2-1]<B[k/2-1],那么B[k/2]就是数组A和B的第k小的数字,以下面的数组为例,如果取k=4,那么A[k/2-1]=A[1]=3,B[k/2-1]=B[1]=4,那么比B[1]小的数恰好有3个,那么B[1]就是A和B中第4小的元素。
接下来分析边界条件:
(1) 如果A和B有一个为空,那么只需要返回另外一个数组的中间数;
(2) 如果(m+n)/2=1,只需返回A[0]和B[0]中的较小数;
AC代码如下:
class Solution {
public:
double findMedianSortedArrays(int A[], int m, int B[], int n) {
int total=m+n;
if(total & 0x1 == 1) return findKth(A,m,B,n,total/2+1);
else return (findKth(A,m,B,n,total/2) + findKth(A,m,B,n,total/2+1) )/2.0;
}
int findKth(int A[],int m,int B[],int n,int k){
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 ai=min(m,k/2),bi=k-ai;
if (A[ai-1]>B[bi-1]) return findKth(A,m,B+bi,n-bi,k-bi);
else if (A[ai-1]<B[bi-1]) return findKth(A+ai,m-ai,B,n,k-ai);
else return A[ai-1];
}
};
代码分析:
上述解答中的findKth函数用于寻找A,B数组中第k小的数字,前面的三个if解释如下:
(1)if (m>n) return findKth(B,n,A,m,k);将长度较短的数组放在后面,方便后面进行判断;
(2)if (m==0) return B[k-1];
if (k==1) return min(A[0],B[0]);
对应于前面讨论的边界条件;
(3)后面取ai=min(m,k/2),bi=k-ai,如果这两个下标对应的数字相等,则A[ai-1]就是第k小的数,因为ai和bi的下标之和为k;如果A[ai-1]>B[bi-1],那么B中从0~bi-1都小于A[ai-1],在A,B中找第k小的数就转换为在A,B+bi中寻找第k-bi小的数;当A[ai-1]<B[bi-1]的时候同理。
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)).
初看到这一题的思路是按照插入排序的思路将两个已经排好序的数组合并到一起,然后按照直接在新合并的数组中找到中间位置的数,这样的算法时间复杂度为O(m+n),这样的代码也可以通过,因为Leetcode的测试样例目前还不能检测log(n)和O(n)的差异,但是看这一题目要求是要求时间复杂度为log(m+n)。初看这题很简单,其实不然,后来在Leetcode的讨论板上看到了解决方法。其实这一题就是寻找两个数组的第k小位置的数,假定A和B都是按照升序排列的(这个不影响问题的分析),如果A[k/2-1]<B[k/2-1],那么B[k/2]就是数组A和B的第k小的数字,以下面的数组为例,如果取k=4,那么A[k/2-1]=A[1]=3,B[k/2-1]=B[1]=4,那么比B[1]小的数恰好有3个,那么B[1]就是A和B中第4小的元素。
接下来分析边界条件:
(1) 如果A和B有一个为空,那么只需要返回另外一个数组的中间数;
(2) 如果(m+n)/2=1,只需返回A[0]和B[0]中的较小数;
AC代码如下:
class Solution {
public:
double findMedianSortedArrays(int A[], int m, int B[], int n) {
int total=m+n;
if(total & 0x1 == 1) return findKth(A,m,B,n,total/2+1);
else return (findKth(A,m,B,n,total/2) + findKth(A,m,B,n,total/2+1) )/2.0;
}
int findKth(int A[],int m,int B[],int n,int k){
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 ai=min(m,k/2),bi=k-ai;
if (A[ai-1]>B[bi-1]) return findKth(A,m,B+bi,n-bi,k-bi);
else if (A[ai-1]<B[bi-1]) return findKth(A+ai,m-ai,B,n,k-ai);
else return A[ai-1];
}
};
代码分析:
上述解答中的findKth函数用于寻找A,B数组中第k小的数字,前面的三个if解释如下:
(1)if (m>n) return findKth(B,n,A,m,k);将长度较短的数组放在后面,方便后面进行判断;
(2)if (m==0) return B[k-1];
if (k==1) return min(A[0],B[0]);
对应于前面讨论的边界条件;
(3)后面取ai=min(m,k/2),bi=k-ai,如果这两个下标对应的数字相等,则A[ai-1]就是第k小的数,因为ai和bi的下标之和为k;如果A[ai-1]>B[bi-1],那么B中从0~bi-1都小于A[ai-1],在A,B中找第k小的数就转换为在A,B+bi中寻找第k-bi小的数;当A[ai-1]<B[bi-1]的时候同理。
相关文章推荐
- [LeetCode] 4.Median of Two Sorted Arrays
- leetcode Median of Two Sorted Arrays
- LeetCode 4 Median of Two Sorted Arrays
- LeetCode 4 - Median of Two Sorted Arrays
- LeetCode: Median of Two Sorted Arrays
- 【leetcode】4. Median of Two Sorted Arrays
- [leetcode]t002-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 (c++ and python version)
- LeetCode题解(Golang实现)--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【4】Median of Two Sorted Arrays
- [Leetcode]4. Median of Two Sorted Arrays @python
- LeetCode 4. Median of Two Sorted Arrays
- Java [leetcode 4] Median of Two Sorted Arrays