给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是你不能重复利用这个数组中同样的元素。
- 暴力循环法(MyVersion)
vector<int> two;
for(int i =0;i < nums.size()-1;++i){ //不要越界
for(int j = i +1 ;j < nums.size();++j)
{
if(nums.at(i) + nums.at(j) == target)//vector.at()
{
two.push_back(i);
two.push_back(j);
break; //及时终止,减少循环
}
}
}
return two; //可以不新建vector,直接返回{i,j }
- 将每个元素与对应的索引存到哈希表中,第二次循环中查看补元素是否存在于哈希表中,且该补元素不能是i本身
unordered_map<int, int> helpMap; // 提供一对一的hash
for (int i = 0; i < nums.size(); i++)
{
helpMap[nums[i]] = i;
}
for (int i = 0; i < nums.size(); i++)
{
int complement = target - nums[i];
if (helpMap.count(complement) && helpMap[complement] != i)
{
return { i, helpMap[complement] };
}
}
return {};
注意特殊情况,如[4, 4, 5, 2, 9], target为8。此时map中第一个4的key-value对被第二个覆盖。相当于具有同一数据时只记录最后一个出现的键值对,第二步查找因为是依靠数组,故不会丢失信息,即使存在重复情况也不会影响查找。
3.一遍哈希表边插入索引边查找,减少占用的内存
unordered_map<int, int> helpMap; // 提供一对一的hash
int size = nums.size();
for (int i = 0; i < size; i++)
{
if (helpMap.count(target - nums[i])) // 返回的是被查找元素的个数
{
return{ helpMap[target - nums[i]],i };
}
helpMap[nums[i]] = i; // 反过来放入map中,用来获取结果下标
}
return {};