leetcode第1题. 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
思路
很明显暴力的解法是两层for循环查找,时间复杂度是O(n^2)。
使用哈希法最为合适,之前已经介绍过,数组和set在哈希法中的应用,那么来看一下使用数组和set来做哈希法的局限。
①数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
②set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下表位置,因为要返回x 和 y的下表。所以set 也不能用。
此时就要选择另一种数据结构:map ,map是一种key value的存储结构,可以用key保存数值,用value在保存数值所在的下表。
所以我们可以用一个unordered_map<int, int> m,key存储数组元素值,value存储值对应下标。为什么不是key存下标,value存值?
c++代码
class solution
{
public:
vector<int> twoSum(vector<int>& vec, int target)
{
unordered_map<int, int> m;
for (int i = 0; i < vec.size(); i++)
{
auto iter = m.find(target - vec[i]); //auto C++11新标准内容,在map中查找是否存在满足条件的对组。
//前面使用key存值,value存下标是方便这里进行查找,find只能查找key,所以将值作为key。
//因为明确两数之和,所以判断数组中是否存在【目标值 - 当前遍历到的元素】的值即可。三数、四数怎么办???
if (iter != m.end())
{
//返回的迭代器不为end(),说明数组中存在该值,返回这两元素下标
return {iter->second, i}; //{} c++11新标准:列表初始化
}
//不在则添加到map中。相当于用vec 初始化map了(参考昨天用nums 初始化set)
m.insert([vec[i], i); //m.insert(pair<int, int>(vec[i], i)) 对组添加方式,m.insert(make_pair(vec[i], i))
}
//退出for循环没有返回说明没有满足条件的两个数
return {};
}
};
原文:哈希表:map等候多时了