LeetCode:2Sum

本文介绍了一种高效的算法来解决数组中寻找两个数使其和等于特定目标数的问题。通过使用排序和双指针技巧,可以在O(nlogn)的时间复杂度内解决问题。另外,还介绍了使用哈希表的方法,可以将时间复杂度降低至O(n),适用于数据量较大的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution.(前提:假设每组输入恰好只有一个解)

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

分析:

思路1:将数字进行升序排列,然后调用两个指针,分别指向头尾。如果头与尾之和大于target,则尾向前移动;如果相等,则返回;如果小于,则头向后移动;(注意事项:在排序之前要记得保存原来数字的下标位置,不然排序后下标会乱)。

代码如下:

vector<int> twoSum(vector<int> &numbers, int target) 
{
	int n=numbers.size();
	int left=0,right=n-1;
	int index[2]={0,0};
	int i=0,j=0;
	vector<int> result;
	int *p=new int[n];
	for(i=0;i<n;i++)
		p[i]=numbers[i];                                //O(n)
	QuickSort(numbers,n,left,right);   //快速排序     O(nlogn)
	while(left<right)        //O(n)
	{
		if(numbers[left]+numbers[right]==target)
		{
			for(i=0;i<n;i++)         //找原始下标   O(n)
			{
				/*if(p[i]==numbers[left])   //易错点:如果numbers中有数相等的情况,会出现覆盖index1的情况
					index1 = i+1;
				else if(p[i]==numbers[right])
					index2 = i+1;*/
				if(p[i]==numbers[left] || p[i]==numbers[right])   
					index[j++] = i+1;
			}
			if(index[0]<index[1])
			{
				result.push_back(index[0]);
				result.push_back(index[1]);
			}
			else if(index[0]>index[1])
			{
				result.push_back(index[1]);
				result.push_back(index[0]);
			}
			if(p)
			{
				delete [] p;
				p=NULL;
			}
			return result;
		}
		else if(numbers[left]+numbers[right] > target)
			right--;
		else
			left++;
		
	}
	if(p)
	{
		delete [] p;
		p=NULL;
	}
	return result;
}
但是当数据较多的时候, 会超时 。   时间复杂度为O(nlogn);

思路2:使用hash,将值作为键,将下标作为值。(无序用hashmap(C++11中是unorder_map),有序用map)

vector<int> twoSum(vector<int>&numbers, int target)
{
         multimap<int,int> multimapVec;   //可能值相同
         pair<int,int>pairVec;
         vector<int>vec;
        
         vector<int>::iteratoriter = numbers.begin();
         for(inti=0 ; iter!=numbers.end(); iter++,i++)
                   multimapVec.insert(make_pair(*iter,i+1));    O(nlogn),构建红黑树
        
         multimap<int,int>::iterator iter1 = multimapVec.begin(),iter2;
         for(i=0; iter1!=multimapVec.end(); iter1++)   //O(n)
         {
                  int re = target - iter1->first;
                   pairVec= *iter1;
                   multimapVec.erase(iter1);//如果剩余的值和原来一样,会出问题,所以需要删去
                   iter2= multimapVec.find(re);    //如果没有找到,则返回end迭代器,O(logn)
                   if(iter2== multimapVec.end()) 
                            continue;
                   else
                   {
                            if(pairVec.second> iter2->second)   //找到目标,从小到大输出
                            {
                                     vec.push_back(iter2->second);
                                     vec.push_back(pairVec.second);
                            }
                            elseif(pairVec.second < iter2->second)
                            {
                                     vec.push_back(pairVec.second);
                                     vec.push_back(iter2->second);
                            }
                            break;
                   }
         }
         return vec;
}</span>





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值