分析
输入: 整数数组nums, 整数目标值target
输出: 数组下标result
限制条件:
- 两个整数的和为目标值(即result的长度为2)
- 数组中同一个元素在答案里不能重复出现(即result的两个元素不同)
- 假设每种输入只会对应一个答案,可以按任意顺序返回答案(即result两个元素任意顺序均可,都视为一个答案)
方法一:暴力法(时间复杂度为)
暴力解决方案就是使用双层for循环,只需要注意边界条件,尽量减少不必要的循环。
Javascript 代码实现
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
let result = [];
for (let i=0; i< nums.length - 1; i++) { //注意边界条件
for (let j=i+1; j<= nums.length - 1; j++) { // 注意边界条件
if (nums[j] + nums[i] === target) {
result = [i, j]
return result
}
}
}
return result;
};
方法二:哈希表
当我们需要查询一个元素是否出现过,或者一个元素是否在集合里,就要第一时间想到哈希表。参考代码随想录
这道题我们不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,所以使用map存放正合适。 最终要返回下标,所以我们将下标作为value, 元素作为key。
Javascript 代码实现
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
let result = [];
// map中的存储结构为 { key:数据元素, value:数组元素对应的下标 }
let map = new Map();
for (let i=0; i<= nums.length - 1; i++) {
if (map[target - nums[i]] !== undefined) { // 说明我们访问过的元素中有整数target-nums[i]
result = [i, map[target-nums[i]]];
return result;
}
// map存放我们访问过的元素
map[nums[i]] = i;
}
return result;
};
一些思考
第一次刷这道题的时候,一直想不通的是以数组中的元素作为key值,很有可能重复呀,而map的key值不能重复,为何代码可以这么写?其实是因为题目中假设每种输入只会对应一个答案。
-
如果有3个或者以上的重复元素,代表这个重复元素不可能是解(如果这个重复元素是我们要找的整数,那么答案就不唯一了)。
-
如果有2个重复元素,要么不是解,写入map的时候因为key值重复被覆盖也无所谓;要么这两个重复元素的和就是target, 这时候已经return result了,第二个重复元素不会写入map, 所以这种情况在编码时已经考虑到了。