question:
Given an array of integers, find two numbers such that they add up to a specific target number.
Output: index1=1, index2=2
思路:
输入一个无序数组和一个目标和,求出两个数之和为这个目标数的下标,有大小之分。
目前想到三种方法:
(1)暴力枚举法
遍历整个数组,测试target与该数的差是否也在数组中,如果在,则这两个数就是要找的,求出其下标即可。
时间复杂度为O(N*N),提交时提醒超时,被鄙视了。
(2)借助hashtable
C++ STL中没有可以直接使用的hashtable模板类,可以使用其他库实现的hashtable或者自己写一个。
hashtable可以在O(1)时间复杂度下查找到一个元素,因此利用hashtable实现暴力枚举法,时间复杂度会降低为O(N)
(3)双指针
首先对数组排序,初始时一个指针指向数组第一个元素,另外一个指针指向最后一个元素,如果两数之和大于target,右指针左移,相反,左指针右移。
排序时间复杂度为O(N*lg N),查找时间复杂度为O(N),所以整体时间复杂度为O(N*lg N)
解题:
利用方法3中的思路
class Solution {
public:
vector<int> twoSum(vector<int> &numbers, int target) {
vector<int> tmp(numbers.size());//新建一个等大的数组
vector<int> res;//用于保存结果
copy(numbers.begin(),numbers.end(),tmp.begin());//复制
sort(tmp.begin(),tmp.end());//排序
vector<int>::iterator start=tmp.begin();//左指针
vector<int>::iterator terminate=tmp.end()-1;//右指针
while((*start+*terminate)!=target)
{
if((*start+*terminate)>target)
terminate--;
if((*start+*terminate)<target)
start++;
}
/*如果数组中有两个相同的元素之和为target,那么find()函数找到的是第一个元素,所以要注意*/
vector<int>::iterator a;
vector<int>::iterator b;
if(*start!=*terminate)
{
a=find(numbers.begin(),numbers.end(),*start);
b=find(numbers.begin(),numbers.end(),*terminate);
}
else
{
a=find(numbers.begin(),numbers.end(),*start);
b=find(a+1,numbers.end(),*terminate);//第二次查找起点不一样
}
res.push_back(a-numbers.begin()+1);
res.push_back(b-numbers.begin()+1);
sort(res.begin(),res.end());
return res;
}
};原文:http://blog.csdn.net/hustyangju/article/details/42672619