您的位置:首页 > 其它

LeetCode 4 - Median of Two Sorted Arrays

2015-05-12 11:04 267 查看

一、问题描述


Description:

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)).



有两个有序的数组 nums1 和 nums2,大小分别为 m 和 n。找出这两个有序数组的中位数,要求时间复杂度为O(log(m+n))。

二、解题报告

解法一:暴力法

题目要求里写了要求时间复杂度为O(log(m+n)),然而直接暴力解决(时间复杂度O(m+n))也能够AC,我不知道为什么。

所谓暴力法,就是直接合并两个有序数组,然后返回合并后的数组的中位数。

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
vector<int> nums;
int M = nums1.size();
int N = nums2.size();
int i=0, j=0;
while(i<M && j<N)
{
if(nums1[i] < nums2[j])
nums.push_back(nums1[i++]);
else
nums.push_back(nums2[j++]);
}

while(i<M)
nums.push_back(nums1[i++]);
while(j<N)
nums.push_back(nums2[j++]);

if((M+N)%2 == 0)  // 偶数
return (nums[(M+N)/2]+nums[(M+N)/2-1])/2.0;
else
return nums[(M+N)/2];
}


解法二:分治法

采用分治法的思想是求两个有序数组的第 k 小数,而中位数就是第 m+n2 小的数。

假设数组A和B的元素个数都大于k2,我们比较 A[k2−1] 和 B[k2−1] 两个元素,这两个元素分别表示A的第 k2 小的元素和B的第 k2 小的元素。这两个元素比较共有三种情况:>、<和=。

当A[k2−1]<B[k2−1] ,这表示A[0]~A[k2−1]的元素都在A和B合并之后的前k小的元素中。换句话说,我们要在剩下的元素里找 k−k2 小的元素。

当A[k2−1]>B[k2−1]时存在类似的结论。

当A[k2−1]=B[k2−1]时,我们已经找到了第k小的数,就是这个相等的元素。

通过上面的分析,我们可以采用递归的方式实现寻找第k小的数。另外需要考虑几个边界条件:

如果 A 或者 B 为空,则直接返回B[k−1]或者A[k−1]

如果k为1,我们只需要返回A[0]和B[0]中的较小值

如果 A[k2−1]=B[k2−1],返回其中一个

函数实现如下:

int findKth(int A[], int m, int B[], int n, int k)
{
if (m > n)    // 保证数组A的大小总是小于数组B的大小
return findKth(B, n, A, m, k);
if (m == 0)   // 如果A为空
return B[k - 1];
if (k == 1)   // 如果k为1
return min(A[0], B[0]);

// 每次把k分两半
int pa = min(k/2, m);  /*A的元素可能小于k/2个*/
int 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];
}


下面是 Solution:

class Solution {
public:
int findKth(int A[], int m, int B[], int n, int k) { if (m > n) // 保证数组A的大小总是小于数组B的大小 return findKth(B, n, A, m, k); if (m == 0) // 如果A为空 return B[k - 1]; if (k == 1) // 如果k为1 return min(A[0], B[0]); // 每次把k分两半 int pa = min(k/2, m); /*A的元素可能小于k/2个*/ int 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]; }

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int *A = nums1.data();
int *B = nums2.data();
int m = nums1.size();
int n = nums2.size();

int total = m+n;
if (total%2 == 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;
}
};


LeetCode答案源代码:https://github.com/SongLee24/LeetCode
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: