「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」
前言:
励志每日至少一题,并写下题解,死磕算法,加油
题目
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
难度:简单
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
思路
看到这个问题,我们先说一个技巧,划重点
几乎所有的求和问题都可以用求差问题来解决
所以我们要找哪两个数相加为9,就可以转化为9减数组中的一个数是否等于数组中的其他数
问题来了->如何能快速找到另一个数呢?
只要是查找最快的方法,立马想到哈希表
有的小伙伴会问了,哈希表是什么? 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。
前端里面类似hash表的有map和object。
那map和object有什么区别呢?
- 1.顺序:map按照加入顺序排序,object先数字后字符串
- 2.键类型不同:一个object的键通常是字符串,而map的键可以是任意值,包括函数,对象,基本类型
- 3.支持迭代:map本身就支持迭代,object不支持
那什么时候使用map,什么时候使用object呢?
- 1.当所要存储的是简单数据类型,我们优先使用key
- 2.当需要在单独的逻辑中访问属性或者元素的时候,应该使用 Object,例如:
- 3.JSON 直接支持 Object,但不支持 Map
- 4.Map 会按照插入顺序保持元素的顺序,而Object做不到。
- 5.如果key值不是简单数据类型的话使用Map
在这里我们使用map容器来保存数据,因为数组中的值可能会重复,而object不支持key值重复
所以我们根据上面的思路分析得出结论:
- 设置一个map容器用来记录元素的值和索引
- 进行nums的遍历,如果map中的key值含有目标值与当前值的差值,则返回所对应key的索引,以及当前数组索引j
- 如果未找到,则把当前值作为key,for的索引作为value存储到map容器中
题解
var twoSum = function(nums, target) {
const map = new Map([]);
for (let j = 0; j < nums.length; j++) {
if (map.has(target - nums[j])) {
return [map.get(target - nums[j]), j];
}
map.set(nums[j], j);
}
return false;
};
-
时间复杂度:O(n),我们只用分析量级最大的那段代码的复杂度,这段代码中,量级最大的复杂度当属for循环那一段,他会每个数都循环一遍,所以时间复杂度是O(n)
-
空间复杂度:O(n),我们看一下这个map这个变量,他会随着数据规模j一直增大,所以空间复杂度为O(n)
可能有的同学会问,为什么不直接把所有的值都存储到map中,然后在遍历map呢,这样更符合思考方式,你这一边遍历一边存储,会不会有漏掉的值呢?
第一:我们可以看到return返回的内容 return [map.get(target - nums[j]), j];,是返回的前面存储值的索引和当前数组索引j,所以完全没必要担心会有漏掉的值
第二: 我们这样做更加节省存储空间,比如数组的第一个值和第二个值就构成了答案,那么我们就不用存储后面的值了