leetcode 虐我篇之(二) Two Sum

正所谓有了第一次被虐,就会有第二次。今天,实验室只有我一个人,因为是暑假,大家不是去实习就是回家之类的。剩下我一个人在做导师和一个公司合作的项目。今天周六所以给自己放个假(前几周都是没有周六日,天天去公司干,要死的节奏啊)。看了《爸爸去哪儿》和《中国好声音》放松了一下,然后就弄了一下sae和svn管理。接着就到leetcode网站上看一下题目。第一次做了最上面的题目,这次我就拉到最后,做最后一题,题目是Two Sum

题目的意思也很清楚明白,就是从一个数组中找出两个数,这两个数的和要等于一个目标数,返回这两个数在原来数组中的坐标。我一开始的想法是,直接就两个for循环遍历一下就ok啦。接着就开始写了。

代码如下(注意后面提交发现是错误的):

vector<int> twoSum(vector<int> &numbers, int target) 
{
	//foreach the vector to find two numbers
	vector<int> result;
	vector<int>::size_type index1,index2,size;
	size = numbers.size();

	bool find = false;

	for (index1 = 0;index1 != size; ++index1)
	{
		for(index2 = index1 + 1;index2 != size; ++index2)
		{
			if ( numbers[index1] + numbers[index2] == target)
			{
				find = true;
				break;
			}
		}

		if (find)
		{
			break;
		}
	}

	if (find)
	{
		result.push_back(index1+1);
		result.push_back(index2+1);
	}

	return result;
}

后面一提交,就报错了。是一个超时错误,什么time limited之类的。还举了个超长的数组例子。怎么原来还需要考虑时间复杂度?!好吧,让我再想想。怪不得通过率只有十几。

然后我想,要提高时间,那就先排序呗,排完序再找,如果加起来数大了,就退出内层循环,这样就省下很多时间啦。但是,如果直接对vector排序的话,那之前的index不就打乱了吗?怎么才能找回对应的呢?然后就想着找另外一个vector<int> index装现在这个numbers的下标,对numbers排序的同时要更新index下标,这样就能够在知道原来index的前提下找出这两个数了。接着就是排序的问题,用什么方法排序呢?冒泡?直接排序?插入排序?堆排序?还是?因为我想着刚才都超时了,现在是不是应该找一个时间复杂度小一点的,然后又想是稳定的(现在想想,好像不稳定的也没关系吧),最后就选归并排序了。在提交后发现又有一个问题,就是要第一个下标要小于第二个下标,唉,没审好题目。改过后提交,Accepted!

修改后的代码如下:

#include <vector>
#define INF 65535;  //表示int 的无穷
using namespace std;

//针对是vector<int>的情况
/合并排序
void merge2vector(vector<int> &Array,vector<int> &Array2,int p,int q,int r)
{
	int n1=q-p+1;
	int n2=r-q;
	int *L=new  int[n1+1];	//动态数组
	int *R=new  int[n1+1];
	int *L2=new  int[n1+1];	//动态数组
	int *R2=new  int[n1+1];
	int i=0,j=0;
	for (i=0;i<n1;i++)
	{
		L[i] = Array[p+i];
		L2[i] = Array2[p+i];
	}

	for (j=0;j<n2;j++)
	{
		R[j] = Array[q+j+1];
		R2[j] = Array2[q+j+1];
	}

	L[n1]=INF;
	R[n2]=INF;
	L2[n1]=INF;
	R2[n2]=INF;
	i=0;
	j=0;
	for (int k=p;k<=r;k++)
	{
		if (L[i]<=R[j])
		{
			Array[k]=L[i];
			Array2[k]=L2[i];
			i++;
		} 
		else
		{
			Array[k]=R[j];
			Array2[k]=R2[j];
			j++;
		}
	}

	delete[] L;
	delete[] L2;
	delete[] R;
	delete[] R2;
}

void mergeSort2vector(vector<int> &Array,vector<int> &Array2,int p,int r)
{
	if (p<r)
	{
		int q=(p+r)/2;
		mergeSort2vector(Array,Array2,p,q);
		mergeSort2vector(Array,Array2,q+1,r);
		merge2vector(Array,Array2,p,q,r);
	}
}


vector<int> twoSum(vector<int> &numbers, int target) 
{
	//先用归并排序
	vector<int> result;
	vector<int>::size_type ind,index1,index2,size;
	size = numbers.size();

	if (size <= 0 )
	{
		return result;
	}

	//下标容器
	vector<int> index;
	for (ind = 0;ind < size;ind++)
	{
		index.push_back(ind+1);
	}

	//开始归并排序
	mergeSort2vector(numbers,index,0,size-1);

	//排序完毕,开始遍历查找


	bool find = false;

	for (index1 = 0;index1 != size; ++index1)
	{
		for(index2 = index1 + 1;index2 != size; ++index2)
		{
			if ( numbers[index1] + numbers[index2] == target)
			{
				find = true;
				break;
			}
			else if ( numbers[index1] + numbers[index2] > target)
			{
				break;
			}
		}

		if (find)
		{
			break;
		}
	}

	if (find)
	{
		int temp = index[index1];
		if (index[index1] > index[index2])
		{
			index[index1] = index[index2];
			index[index2] = temp;
		}
		result.push_back(index[index1]);
		result.push_back(index[index2]);
	}

	return result;
}
总觉得这道题是不是有其他简便的方法呢。唉,喉咙痛感冒头晕中,暂时不想了。准备睡觉。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值