Leetcode第四题 Median of Two Sorted Arrays

要求中位数,关键是要找到第k小的数,命名为findk()。这里我们分为两种情况分析,如果是数组的长度为奇数,只调用一次findk();如果是数组的长度是偶数则调用2次findk()。

Findk()的算法为:

(1)判断A[k/2-1]与B[k/2-1]的大小(也就是取两个数组中前k/2个数),如果数组的长度不足k/2,用A[max-1],B[max-1]来取代,这里使用index表示,index=min(k/2-1,max/2-1),A的index为记作index1,B的index记作index2。

1.1如果A[index1]>B[index2],则说明B[0]~B[index2]的数都不会是第K小的数,所以将这index2+1个数去掉,现在问题转化为剩下的m+n-index2-1个数中第k-index2-1小的数,即m=m,n=n-index2-1,k=k-index2-1,回到步骤(1)

1.2如果A[index1]=B[index2],要分两种情况讨论。如果k为偶数则A[index1]就是我们需要的数,如果k为奇数,则所取的数都是无用的,因为/代表的是取整计算。比如k=5,则我们总共取出来4个数,而且第3、4个是相等,所以这4个数都可以都是可以舍掉的。返回步骤(1)

1.3如果A[index1]<B[index2],如1.1所述,去掉A中前index+1个数,此时m=m-index-1,n=n,k=k-index1-1,回到步骤(1)

至此迭代的主循环已经完成。按照最坏的情况计算,每次去掉k/2个数,直到k=1时,

min(A[0,B[0])即为所求,这样k的变化为k,k/2,k/4…..(事实上这里存在一个k-k/2!=k/2的问题),经过n次迭代之后 ,可得时间复杂度为n=logk。

程序中的几点注意事项:

1. 如果是空向量vc,那么vc.begin()和vc.end()等无意义,会报错!

2.对于vs2010而言并不支持列表初始化如vector<int>nums{1,2,3};对向量初始化要通过push_back()

3..向量的erase操作的参数是迭代器,原先一直以为是下标。同时需特别注意erase之后指向该元素的迭代器将会失效。比如

iter1=nums.begin()+1;

nums.erase(iter1);

cout<<*iter1;

//此时访问将会出错 not dereferencable

 

4 函数声明时像void fun(vector<int>&num),num是原向量的引用,对原向量进行了地址的传递,对num的操作即为对原向量的操作,如果函数名是void fun(vector<int >num), 则仅仅是值传递对num的操作并不会影响原向量。

5.两个向量可以相互赋值,如vec1=vec,这两个向量的值是相同的,仅仅是赋值,对Vec1的操作并不会影响vec。

int findk(vector<int> nums1, vector<int> nums2,int k)
{
	int m=nums1.size(); int n=nums2.size();
	int index1,index2;
	vector<int>::iterator iter1,iter2;
	index1=min(m-1,k/2-1);
	index2=min(n-1,k/2-1);
	if (nums1.empty())   //如果有一个为空直接返回中位数
		return nums2[k-1];
	if(nums2.empty())
		return nums1[k-1];
	if (k==1)
		return min(nums1[0],nums2[0]);
	iter1=nums1.begin()+index1;
	iter2=nums2.begin()+index2;
	
	if (nums1[index1]>nums2[index2])
	{
		nums2.erase(nums2.begin(),iter2+1);//舍掉前index2 +1个
		k=k-index2-1;
	}
	else if (nums1[index1]<nums2[index2])
	{
		nums1.erase(nums1.begin(),iter1+1);
		k=k-index1-1;
	}
	else 
	{
		if (k%2)//奇数相等都舍掉
		{
			nums2.erase(nums2.begin(),iter2+1);
			nums1.erase(nums1.begin(),iter1+1);
			k=k-index1-index2-2;
		}
		else //偶数相等返回中位数
			return nums1[index1];
	}
	
	return findk(nums1,nums2,k);

}

class Solution {
public:
	double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
			int m,n,temp1,temp2;
			double median;
			m=nums1.size();
			n=nums2.size();
			if ((m+n)%2)
			{
				 median=findk(nums1,nums2,(m+n)/2+1);
				
			}
			else
			{
				temp1=findk(nums1,nums2,(m+n)/2);
				temp2=findk(nums1,nums2,(m+n)/2+1);
				median=(temp1+temp2)*1.0/2;
			}
		return median;
	}
};



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值