LeetCode Median of Two Sorted Arrays

题目来源:https://leetcode.com/problems/median-of-two-sorted-arrays/

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

题目要求:两个排序数组中,计算出他们的中位数。中位数的概念:数列中的个数是奇数时,中位数是中间数,否则,是中间两个数的平均数。

刚开始把O(log(m+n))错误的以为是O(m+n),所以想到的就是归并排序的思路,讲所有数据进行排序,然后可以取得中位数。最后,去LeetCode测试Accept了,谁知道等我开写博客的时候,才发现时间复杂度要求为O(log(m+n))。废话不说,先把O(m+n)的代码贴上来。

class Solution {
public:
    int getOneStoredArray(vector<int> &nums1, vector<int > &nums2, int &p1, int&p2)
{
	if (p1 < nums1.size() && p2 < nums2.size())
	{
		int x = nums1[p1];
		int y = nums2[p2];
		if (x < y)
		{
			p1++;
			return x;
		}
		else
		{
			p2++;
			return y;
		}
	}
	if (p1 < nums1.size())
	{
		p1++;
		return nums1[p1 - 1];

	}
	else
	{
		p2++;
		return nums2[p2 - 1];
	}

}
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        if (nums1.size() == 0 && nums2.size() == 0)
		return 0;
	int nums1_pointer = 0, nums2_pointer = 0;
	int size = nums1.size() + nums2.size();
	if (size % 2 == 0)
	{
		int cnt = size / 2;
		for (int i = 0; i < cnt-1; i++)
		{
			getOneStoredArray(nums1, nums2, nums1_pointer, nums2_pointer);
		}
		int x = getOneStoredArray(nums1, nums2, nums1_pointer, nums2_pointer);
		int y = getOneStoredArray(nums1, nums2, nums1_pointer, nums2_pointer);
		return (x + y) / 2.0;
		
	}
	else
	{
		int cnt = size / 2 + 1;
		for (int i = 0; i < cnt-1; i++)
		{
			getOneStoredArray(nums1, nums2, nums1_pointer, nums2_pointer);
		}
		return getOneStoredArray(nums1, nums2, nums1_pointer, nums2_pointer);
	}
    }
};
那么如果想要复杂度要求是O(log(m+n)),第一感觉就是寻找log(N)的算法,二分查找的复杂度是log(N)。想到的第一种思路是,求出两个列表的中位数x和y,然后将两个数组中同时小于x和y的一部分删除,然后再使用第k小值的算法。但是最终没有具体算法。

第二种思路:中位数实际上就是第(m+n)/2的数,所以直接使用第k小值的算法。

具体思路在于,将两个数组每次拿去k/2的元素个数,然后求接下来求第k-k/2小值元素。

方法:首先求出数组x=nums1[k/2]  y=nums2[k/2]。然后比较x和y的数值,如果x小,则直接移走nums1的前k/2个元素,然后求第k-k/2小值元素,否则,移走nums2的前k/2个元素,然后求第k-k/2小值元素(当然实际情况下,还需要考虑num1和nums2的长度是否大于k/2)。

期中还有三个基本情况:

1. nums1的长度为0,直接返回nums2的第k个元素即可。

2. mums2的长度为0,直接返回nums1的第k个元素。

3. 如果k==1,直接返回nums1[0]和nums2[0]的最小值。

代码如下:

class Solution {
public:
    int getOneStoredArray(vector<int> &nums1, vector<int > &nums2, int nums1begin,int nums1end,int nums2begin,int nums2end,int kth)
{
	
	if (nums1begin >= nums1end)
		return nums2[nums2begin + kth - 1];
	if (nums2begin >= nums2end)
	{
		return nums1[nums1begin + kth - 1];
	}
	if (kth == 1)
	{
		int x = nums1[nums1begin];
		int y = nums2[nums2begin];
		return x<y?x:y;
	}
	int index1 = nums1begin + kth / 2 - 1;
	int index2 = nums2begin + kth / 2 - 1;
	if (index1 >= nums1end)
		index1 = nums1end-1;
	if (index2>=nums2end)
		index2 = nums2end - 1;
	if (nums1[index1] < nums2[index2])
	{
		return getOneStoredArray(nums1, nums2, index1 + 1, nums1end, nums2begin, nums2end, kth - index1 + nums1begin - 1);
	}
	else
	{
		return getOneStoredArray(nums1, nums2, nums1begin, nums1end, index2+1, nums2end, kth - index2 + nums2begin - 1);
	}


} 
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
    int m = nums1.size();
	int n = nums2.size();
	if (m + n == 0)
		return 0;
	if ((m + n) & 1 == 1)
	{
		return getOneStoredArray(nums1, nums2, 0, nums1.size(), 0, nums2.size(), (m + n) / 2 + 1);
	}
	else
	{
		int x = getOneStoredArray(nums1, nums2, 0, nums1.size(), 0, nums2.size(), (m + n) / 2 + 1);
		int y=getOneStoredArray(nums1, nums2, 0, nums1.size(), 0, nums2.size(), (m + n) / 2 );
		return (x + y) / 2.0;
	}
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值