C++
暴力:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ans;
for(int i=0; i<nums.size()-1; i++)
{
for(int j=i+1;j<nums.size(); j++)
{
if(nums[i]+nums[j]==target){
ans.push_back(i);
ans.push_back(j);
return ans;
}
}
}
return ans;
}
};
哈希:
class Solution
{
public:
vector<int> twoSum(vector<int>& nums, int target)
{
unordered_map<int,int> unmap;
for(int i=0; i<nums.size(); ++i){
unmap[nums[i]] = i;
}
vector<int> ans;
for(int j=0; j<nums.size(); ++j){
int a = target - nums[j];
if((unmap.find(a) != unmap.end()) && (unmap[a] != j)){
ans.push_back(j);
ans.push_back(unmap[a]);
return ans;
}
}
return ans;
}
};
哈希表的key值是唯一的,代码中 unomap[nums[i]] = i; nums[i]的值可能会发生重复,以测试用例:输入 nums = [3,3] target = 6 输出 [0,1] 为例子:
-
第一次循环建立哈希表:
- 当
i = 0
时,nums[0] = 3
,因此unomap[3] = 0
。 - 当
i = 1
时,nums[1] = 3
,由于键3
已经存在于哈希表中,它会被更新为unomap[3] = 1
。
- 当
-
第二次循环查找匹配项:
- 当
i = 0
时,nums[0] = 3
,计算得到d = 6 - 3 = 3
。此时unomap.find(3)
返回的是哈希表中键为3
的项,其值为1
。因为1 > 0
,所以满足条件,将索引0
和1
存入ans
并返回。
- 当
因此,尽管哈希表中键被覆盖了,但是结果还是正确的。
不过如果想避免这个情况,可以使用std::unordered_map<int, vector<int>>
来存储每个数值出现的所有位置。 (代码放最下面)
优化:只遍历一次
class Solution
{
public:
vector<int> twoSum(vector<int>& nums, int target)
{
unordered_map<int,int> unmap;
vector<int> ans;
for(int i=0; i<nums.size(); ++i){
int a = target - nums[i];
if(unmap.find(a) != unmap.end() && unmap[a] != i){
ans.push_back(i);
ans.push_back(unmap[a]);
return ans;
}
unmap[nums[i]] = i;
}
return ans;
}
};
使用std::unordered_map<int, vector<int>>
class Solution
{
public:
vector<int> twoSum(vector<int>& nums, int target)
{
unordered_map<int, vector<int>> unomap;
vector<int> ans;
for (int i = 0; i < nums.size(); ++i)
{
int a = target - nums[i];
if (unomap.find(a) != unomap.end() && !unomap[a].empty())
{
for (int j : unomap[a])
{
if (j != i)
{
ans.push_back(j);
ans.push_back(i);
return ans;
}
}
}
unomap[nums[i]].push_back(i);
}
return ans;
}
};