Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
不是难题。顺便可以记录一下开始刷LeetCode的第一天。
第一种方法:暴力也是最简单的解法,选中一个数然后遍历其他的数,计算和值是否满足要求。算法时间复杂度O()。
第二种方法:显然这种方法不是一个算法的学习者爱好者该有的,那么怎样在确定一个数的时候迅速的得知另一个数是否存在呢?hash表可以解决这个问题。只要遍历一遍列表记住每个数字以及对应的位置即可。然后再次遍历数组或者是map,确定一个数a,查看 target - a是否存在于hash表里,如果不存在则继续寻找,如果存在则返回a 和 target - a的位置。
不过在这里还是有一个问题的,我觉得这道题可能是我理解的不到位或者出题者说的有点含混不清,因为题目中说 not use the same element twice. 这个元素是指什么呢,同一个位置还是同一个数字呢。所以我在程序中使用了 map<int, vector<int> > 来进行记录,同时会处理 a == target - a 这种情况。算法时间复杂度O(N)。
上边说的第二种方法在我看到LeetCode的解析的时候发现还有第三种,其实是第二种方法的加强版,但是实在是佩服的五体投地。在我们遍历数组放入map中的时候,不放把判断也加入到其中来。假设a + b = target 并且 a 的下标小于 b,那么在遍历到a位置的时候时是没有b的存在的,但是当遍历到b的时候,a已经放入了map,这时就可以对其进行输出了,根本不需要再遍历第二遍。受教受教。
AC代码:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int, vector<int> > nummap;
vector<int> result;
for(int i = 0; i < nums.size(); ++i) {
nummap[nums[i]].push_back(i);
}
for(map<int, vector<int> >::iterator it = nummap.begin(); it != nummap.end(); ++it) {
int b = target - it->first;
if(b * 2 == target && (it->second).size() > 1) {
result.push_back((it->second)[0]);
result.push_back((it->second)[1]);
break;
} else if(nummap.find(b) != nummap.end()) {
result.push_back((it->second)[0]);
result.push_back(nummap[b][0]);
break;
}
}
return result;
}
};
如有错误,欢迎指摘