您的位置:首页 > 其它

Leetcode:Median of Two Sorted Arrays

2015-07-31 16:21 483 查看

Question

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

Solution

方案一:将两个数组合成一个数组,使用快速排序算法进行排序,然后找到中位数。

  空间复杂度:

O(m+n)O(m+n)

  时间复杂度:

  O(log(m+n))O(log(m+n))

方案二:对nums1和nums2数组分别使用二分查找法,直到最后两个数组剩下一个或两个元素,这样就很容易找到中位数。

  空间复杂度:

  O(1)O(1)

  时间复杂度:

  O(log(max(m,n))O(log(max(m, n))

方案一代码:

  这里我没有自己编写快速排序算法,使用的是python的内建函数。最后的平均速度是124ms。

class Solution:
# @param {integer[]} nums1
# @param {integer[]} nums2
# @return {float}
def findMedianSortedArrays(self, nums1, nums2):
alln = nums1 + nums2
alln.sort()
maxn = len(alln)
if maxn % 2 == 1:
return alln[maxn/2]
else:
return ( alln[maxn/2] + alln[maxn/2 - 1] ) / 2.0


方案二代码:

这里的代码总是又几个数据不能运行,所以这个暂时先放一放,代码我就暂时不贴上来了。



其他人的解决方案

C语言

double
findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size)
{
int left = (nums1Size + nums2Size + 1) / 2, right = left;
if((nums1Size + nums2Size) % 2 == 0)
right++;
//printf("left:%d\tright:%d\n", left, right);
//find the left smallest element, comparing from the start of array--O(left)
//BETTER: left/2, left/4, left/8...
int i = 0, j = 0, t = left, k = (t + 1) / 2;
while(k > 0)
{
if(i + k > nums1Size || j + k > nums2Size)
break;
if(nums1[i+k-1] < nums2[j+k-1])
i += k;
else
j += k;
t -= k;
k = (t + 1) / 2;
}
while(t > 0 && i < nums1Size && j < nums2Size)
{
if(nums1[i] < nums2[j])
i++;
else
j++;
t--;
}
if(t > 0)
{
if(i == nums1Size)
j += t;
else if(j == nums2Size)
i += t;
}
int mid_left, mid_right;
if(i > 0 && j > 0)
mid_left = (nums1[i-1] < nums2[j-1])?nums2[j-1]:nums1[i-1];
else if(i == 0)
mid_left = nums2[j-1];
else if(j == 0)
mid_left = nums1[i-1];
if(right > left)
{
if(i < nums1Size && j < nums2Size)
mid_right = (nums1[i] < nums2[j])?nums1[i]:nums2[j];
else if(i == nums1Size)
mid_right = nums2[j];
else if(j == nums2Size)
mid_right = nums1[i];
}
else
mid_right = mid_left;
//printf("mid_left:%d\tmid_right:%d\n", mid_left, mid_right);
return (mid_left + mid_right) / 2.0;
}


C++代码

public:
double findMedianSortedArrays(vector<int>& nums1,vector<int>& nums2)
{
int m,n,k;
m = nums1.size();
n = nums2.size();
auto beg1 = nums1.begin(),beg2 = nums2.begin();
k = (m+n)>>1;
if((m+n) & 0x1)
return find_kth(nums1,beg1,nums2,beg2,k+1);
else
return (find_kth(nums1,beg1,nums2,beg2,k) + find_kth(nums1,beg1,nums2,beg2,k+1))/2.0;

}
private:
double find_kth(vector<int>& nums1,vector<int>::iterator beg1,vector<int>& nums2,vector<int>::iterator beg2,int k)
{
int m = nums1.end() - beg1,n = nums2.end() - beg2;
if(m>n)
return find_kth(nums2,beg2,nums1,beg1,k);
if(m==0) return *(beg2+k-1);
if(k==1) return min(*beg1,*beg2);
int m1 = min(k/2,m),m2 = k-m1;
if(*(beg1+m1-1)<*(beg2+m2-1))
return find_kth(nums1,beg1+m1,nums2,beg2,k-m1);
else if(*(beg1+m1-1)>*(beg2+m2-1))
return find_kth(nums1,beg1,nums2,beg2+m2,k-m2);
else
return *(beg1+m1-1);
}


Java代码

int l1 = -1;
int l2 = -1;
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int tar = (nums1.length + nums2.length);
if (nums1.length * nums2.length == 0) {
if (nums1.length == 0) {
if (tar % 2 == 0)
return (nums2[nums2.length / 2 - 1] + nums2[nums2.length / 2]) / 2.0;
return nums2[nums2.length / 2];
} else {
if (tar % 2 == 0)
return (nums1[nums1.length / 2 - 1] + nums1[nums1.length / 2]) / 2.0;
return nums1[nums1.length / 2];

}

}

if (tar % 2 == 0) {
return (find(tar / 2 - 1, nums1, nums2) + find(0, nums1, nums2)) / 2.0;

} else {
return find(tar / 2, nums1, nums2);

}

}

public int find(int next, int[] nums1, int[] nums2) {

if (next == 0) {
if (l1 == nums1.length - 1) {
return nums2[l2++ + 1];
} else if (l2 == nums2.length - 1) {
return nums1[l1++ + 1];

}
return nums1[l1 + 1] > nums2[l2 + 1] ? nums2[l2++ + 1]
: nums1[l1++ + 1];

}
if (next == 1) {
if (nums1[l1 + 1] > nums2[l2 + 1]) {
l2++;
} else {
l1++;
}
return find(0, nums1, nums2);
} else {
int t1 = (next - 2) / 2 % (nums1.length - 1 - l1) + 1;
int t2 = (next - 2) / 2 % (nums2.length - l2 - 1) + 1;
if (nums1[l1 + t1] >= nums2[t2 + l2]) {
if (t2 + l2 == nums2.length - 1) {
next = next - t2;
l2 = t2 + l2;
l1 = l1 + next;
return nums1[l1++ + 1];
} else {
next = next - t2;
l2 = t2 + l2;
return find(next, nums1, nums2);

}

} else {
if (t1 + l1 == nums1.length - 1) {
next = next - t1;
l1 = t1 + l1;
l2 = l2 + next;
return nums2[l2++ + 1];

} else {
next = next - t1;
l1 = t1 + l1;
return find(next, nums1, nums2);

}

}

}

}


Summarizes

这一道题我花了很长时间,知道对两个数组使用折半搜索,但是最后的地方总是想不明白。内建函数是经过优化的,所以速度会比自己写的函数要快很多,以后如果能使用内建函数的地方,最好还是使用内建函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: