在刷leetcode题目,遇到的第一道题就是给一个整数数组 nums
、整数目标值 target
,在数组中找到和为target的两个坐标。
unordered_map为C++中STL哈希表的实现,unordered_map 可以将键值映射到不同桶中,快速查找对应的键。
1、头文件包含unordered_map
2、定义和初始化,key_type表示键类型,mapped_type表示值类型
// 空 unordered_map
std::unordered_map<key_type, mapped_type> map;
// 大小为 n 的 unordered_map
std::unordered_map<key_type, mapped_type> map(n);
// 大小为 n,值为 value 的unordered_map
std::unordered_map<key_type, mapped_type> map(n, value);
// 复制 another_map 的内容初始化
std::unordered_map<key_type, mapped_type> map(other_map);
// 复制 another_map 的区间初始化
std::unordered_map<key_type, mapped_type> map(other_map.begin(), other_map.end());
3、插入和访问
// 插入一对键值对
map.insert(std::make_pair(key, value));
// 插入一对键值对
map.insert({key, value});
// 插入或覆盖键对应的值
map[key] = value;
4、删除元素
// 删除键为 key 的元素
map.erase(key);
// 删除所有元素,将 unordered_map 置为空
map.clear();
5、迭代器进行遍历
使用map.begin()和map.end()返回unordered_map中的迭代器
for (auto it = map.begin(); it != map.end(); it++)
{
// 获取键
key_type key = it->first;
// 获取值
mapped_type value = it->second;
// ...
}
使用 auto 关键字简化迭代器的定义:
for (auto& [key, value] : map)
{
// ...
}
6、获取元素个数
// 获取元素个数
std::size_t size = map.size();
// 测试 key 是否存在于 unordered_map 中
bool exists = map.count(key) > 0;
思路:
1、创建空的哈希表
2、遍历数组中的每个元素,计算出与目标值 target 的差值 temp。
3、在哈希表中查找是否存在键为 temp 的元素。如果存在,则说明 nums[i] 与之前的某个元素的和等于 target,直接返回它们的下标。
因此,需要使用 unordered_map 数据结构提供的 find 方法,在哈希表 map 中搜索是否存在键为 temp 的元素。如果 find 方法返回的迭代器指向哈希表的尾部,则说明哈希表中不存在键为 temp 的元素,需要将当前元素的值和下标保存到哈希表中。如果存在,则说明数组中存在两个元素的和等于目标值 target,直接返回它们的下标即可。
具体来说,if (map.find(temp) != map.end()) 这一句话,map.find(temp) 返回一个指向哈希表 map 中键为 temp 的元素的迭代器。如果要搜索的元素不存在,则返回指向哈希表尾部的迭代器,即 map.end()。因此,可以通过判断 find 方法的返回值是否等于 map.end() 来判断是否存在键为 temp 的元素,从而决定是否需要将当前元素的值和下标保存到哈希表中。
class Solution
{
public:
vector<int> twoSum(vector<int>& nums, int target)
{
std::unordered_map<int, int> map; // 创建空的哈希表
for (int i = 0; i < nums.size(); i++) // 遍历整个数组
{
int temp = target - nums[i];
if (map.find(temp) != map.end()) // map.find(temp) 返回一个指向哈希表 map 中键为 temp 的元素的迭代器
{
return { map[temp], i };
}
map[nums[i]] = i; // 用于赋值给哈希表
}
throw "No two sum solution"; // 异常处理
}
};
疑问:对C++还不熟悉,所以有很多的疑问。
1、if (map.find(temp) != map.end()) 是干什么的?
if (map.find(temp) != map.end()) 这一句话,map.find(temp) 返回一个指向哈希表 map 中键为 temp 的元素的迭代器。如果要搜索的元素不存在,则返回指向哈希表尾部的迭代器,即 map.end()。因此,可以通过判断 find 方法的返回值是否等于 map.end() 来判断是否存在键为 temp 的元素,从而决定是否需要将当前元素的值和下标保存到哈希表中。
2、throw “No two sum solution”;这一句话是干什么的?
throw 语句抛出一个异常。throw 语句可以将控制权转移到调用该函数的位置,并且带有一个异常对象,该对象可以是一个基本的数据类型(例如 char、int、double 等),也可以是一个自定义的类型。
3、map.find(temp)是不是也会保存temp?
map.find(temp) 函数的作用是查找哈希表中键等于 temp 的元素,并且返回一个指向该元素的迭代器。
复杂度:不考虑,工作原因没必要。其他的方法:个人偏向于积累和实际,没必要一题多解。