之前在网上零零散散也做过一些OJ的题,但都没有leetcode的难。半个月前打开网页,看到第一题,就懵了。看着solution,完全不懂STL,vector,map都是什么鬼。就这样,慢慢地去了解STL,然后知道了容器,迭代器,一步一步到现在能看懂别人的解答。虽然过程不易,但我希望这是一个开始,所以做点记录
解法1:先将原数组复制一份到待排数组,再将待排数组排序,然后类似于快排,使用left,right两个指针,如果两数相加等于sum,则遍历原数组分别找到下标值存到新容器;如果两数相加大于sum,则right--;如果两数相加小于sum,则left++
完整代码如下:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> twoSum(vector<int> &numbers, int target)
{
vector<int> sorted(numbers);
sort(sorted.begin(), sorted.end());
vector<int> result;
int left = 0;
int right = numbers.size() - 1;
int sum = 0;
while(left < right)
{
sum = sorted[left] + sorted[right];
if(sum == target)
{
for(int i = 0; i < numbers.size(); i++)
{
if(numbers[i] == sorted[left])
result.push_back(i+1);
else if(numbers[i] == sorted[right])
result.push_back(i+1);
if(result.size() == 2)
return result;
}
}
else if(sum > target)
right--;
else
left++;
}
}
int main()
{
vector<int> num = {2,11,7,15};
vector<int> res = twoSum(num, 9);
cout<<res[0]<<" "<<res[1];
return 0;
}
解法2:使用unordered_map,数组内容为key,数组下标为value。首先将原数组内容存入map的key,,然后对于原数组中的每个值,用target - 原数组[i]进行遍历,如果发现存在这样的值,并且下标不是i,那么分别将下标存到结果数组
完整代码如下:
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;
vector<int> twoSum(vector<int> &numbers, int target)
{
unordered_map<int,int> numsmap;
vector<int> result;
for(int i = 0; i < numbers.size(); i++)
{
//numsmap.insert(unordered_map<int,int>::value_type(numbers[i],i));
numsmap[numbers[i]] = i;
}
for(int i = 0; i < numbers.size(); i++)
{
// unordered_map<int,int>::iterator iter;
int gap = target - numbers[i];
if(numsmap.find(gap) != numsmap.end() && numsmap[gap] != i)
{
result.push_back(i+1);
result.push_back(numsmap[gap]+1);
break;
}
}
return result;
}
int main()
{
vector<int> num = {2,11,7,15};
vector<int> res = twoSum(num, 9);
cout<<res[0]<<" "<<res[1]<<endl;
return 0;
}
对于此题,个人认为可以有改进,能够手动输入数组元素;当结果不止一对下标时,能够输出多对下标;当找不到下标时,能够有所提示