目录
题干
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6 输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6 输出:[0,1]
数据结构
这道题题目如果用最直接的做法便是遍历数组中每一个元素,在每一次遍历到一个元素时,对其后面的元素也进行遍历,直到找出相加可以等于target值的两个元素。但是这种暴力的做法时间复杂度较高,究其原因是因为进行了对同一元素进行了多次重复的遍历,没有记住遍历过的元素的值。
因此这道题我们依旧要利用到哈希表,但是这一次我们选用的数据结构有所不同,原因在于题干要求我们不仅要找到元素的值还要让我们返回元素所在数组的下标,这就意味着我们需要记住两个信息。而map的key value结构就恰好合适。
map是C++标准模板库(STL)中提供的一种关联式容器。
map用于存储键值对,其中每个键都与一个特定的值相关联。它允许通过键来快速检索对应的值。map内部实现通常是基于红黑树或平衡二叉搜索树,因此它能够保持元素的有序性并提供对数级别的查找、插入和删除操作。
以下是map的一些主要特点:
- 键值对存储:map中的元素以键值对的形式存储,每个键对应一个特定的值。
- 唯一键:map中的键是唯一的,不允许有重复的键存在。
- 有序性:map中的元素会根据键的值自动排序,保持一定的顺序。
- 高效性:由于内部实现是平衡二叉搜索树,map提供了对数级别的查找、插入和删除操作。
- 支持的操作:map支持一系列的操作,如插入新键值对、删除键值对、查找键对应的值等。
总的来说,map是一个非常有用的工具,特别适用于需要通过键来快速检索值的情况。
在map中,key和value是成对出现的,每个key对应一个value。在存储和操作时,通常是以key为主导,通过key来访问和操作对应的value。
具体来说,map的迭代器是一个pair类型的对象,其中first表示key,second表示value。当遍历map时,可以通过迭代器的first成员来获取key,通过second成员来获取value。
map
的 find()
函数返回的是一个迭代器,该迭代器指向在 map
中找到的具有指定键的元素的键值对,或者如果找不到这样的元素,则返回 map::end()
。
但我们这道题目不需要对key 进行排序,所以我们实际采用的是unordered_map。
unordered_map是C++标准模板库(STL)中提供的一种无序关联式容器。
与map不同,unordered_map内部实现是基于哈希表的,而不是红黑树或平衡二叉搜索树。因此,它不保证元素的顺序,并且元素的存储位置是根据键的哈希值决定的。
以下是unordered_map的一些主要特点:
- 键值对存储:unordered_map中的元素以键值对的形式存储,每个键对应一个特定的值。
- 唯一键:unordered_map中的键是唯一的,不允许有重复的键存在。
- 无序性:由于使用哈希表进行存储,unordered_map中的元素没有固定的顺序。
- 高效性:由于哈希表的查找、插入和删除操作的平均时间复杂度为常数级别O(1),所以unordered_map提供了高效的性能。
- 支持的操作:unordered_map支持一系列的操作,如插入新键值对、删除键值对、查找键对应的值等。
总的来说,unordered_map是一种非常快速且高效的数据结构,适用于需要快速检索键值对的场景,但不需要元素有序的情况。
解题思路
遍历数组,每遍历一个元素,进行一次判断,判断哈希表中是否存在等于target- 该元素的值的元素,若存在,则返回对应这两个元素的数组下标,若不存在,则将这个遍历的元素的数组下标和值存储在哈希表中。
map查找的是key而非value,因此我们要把nums[i]作为k,i作为value。
map
的 find()
函数返回的是一个迭代器,该迭代器指向在 map
中找到的具有指定键的元素的键值对,或者如果找不到这样的元素,则返回 map::end()。
当我们在哈希表中找到符合条件的键值对,该如何获取下标呢,这里就用到迭代器了,可以用iter->first和iter->second来表示k和value。
本题我们不需要建立一个结果数组来存储下标,因为只要找到一组就立即返回。
完整代码如下:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
//建立一个map储存遍历过的元素的值和下标
unordered_map<int,int> hash;
//遍历数组
for(int i = 0; i < nums.size(); i++){
//用iter储存mapfind的结果
auto iter = hash.find(target - nums[i]);
//如果在哈希表中找到了target-nums[i]的值
if(iter != hash.end()){
//将i和另一个数的下标加入数组
return {i,iter -> second};
}
//如果没有找到,就把遍历的结果放入哈希表
hash.insert(pair<int,int>(nums[i],i));
}
//遍历完说明没有答案,返回空数组
return {};
}
};