这题比较简单。两种解法:
1) 将原数组 排序后用两个指针,一前一后凑。然后找到后还要从原数组中把index找出来。时间复杂度O(nlogn)
2) 用unordered_map。注意unordered_map内部用Hash实现,所以查找只用O(1),总时间复杂度O(n)。如果用map的话,因为其内部为RB树,查找需要O(logn),所以时间复杂度还是O(nlogn)。
另外 需要注意最后输出的时候
vector<int>{um[diff], i};
不是vector<int>{i, um[diff]}。因为是从前往后扫描,要等到后面才能发现前面已经有了,所以um[diff]放在前面。
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> nums2 = nums;
sort(nums2.begin(), nums2.end());
int p1, p2;
p1 = 0;
p2 = nums.size()-1;
while(p1!=p2) {
if (nums2[p1]+nums2[p2]>target)
p2--;
else if (nums2[p1]+nums2[p2]<target)
p1++;
else
break;
}
vector<int> result;
for (int i=0; i<nums.size(); i++) {
if (nums[i]==nums2[p1])
result.push_back(i);
else if (nums[i]==nums2[p2])
result.push_back(i);
}
return result;
}
#if 0
vector<int> twoSum(vector<int> &numbers, int target) {
unordered_map<int, int> um;
for (int i=0; i<numbers.size(); i++) {
int diff = target - numbers[i];
if (um.count(diff) > 0)
return vector<int>{um[diff], i};
else
//um.insert(make_pair(numbers[i], i)); //两种表示等价
um[numbers[i]]=i;
}
return vector<int>();
}
#endif
int main()
{
vector<int> a = {2,2,5,6};
vector<int> ret = twoSum(a, 4);
for (vector<int>::iterator it= ret.begin(); it!=ret.end(); it++)
cout<<*it<<" ";
return 0;
}
顺便贴一下Leetcode-167 TwoSum II的代码:
这题要注意返回index从1开始。
#include <iostream>
#include <vector>
using namespace std;
vector<int> twoSum(vector<int>& numbers, int target) {
int i=0, j=numbers.size()-1;
vector<int> ret;
while(i<j) {
long long sum=numbers[i]+numbers[j];
if (sum>target) {
j--;
}else if (sum<target) {
i++;
}else {
ret.push_back(i+1); //index starts from 1
ret.push_back(j+1); //index starts from 1
return ret;
}
}
// return ret;
}
int main()
{
vector<int> numbers={2,7,11,15};
vector<int> findIndex=twoSum(numbers, 9);
for (auto i: findIndex) cout<<i<<" ";
return 0;
}