题目:
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
初解题:
- 数组中数字不可以重复使用
- 返回一个数组
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
let result = []
nums.map((first,i) => {
let secondIndex = i + 1
let second = nums[secondIndex]
let sum = first + second
if(sum === target) {
result.push(i,secondIndex)
}
})
return result
};
结论:通过了示例测试,但未未考虑到当数组为 [3,2,3],target = 6的情况
思考后修改如下:
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
let result = []
nums.map((first,i) => {
let secondIndex = i + 1
nums.forEach((second,j) => {
let sum = first + second
if(j >= secondIndex && sum === target) {
result.push(i,j)
}
});
})
return result
};
高手解法:
高手:@tboys
解题思路
哈希表
- 遍历的同时,记录一些信息,省去一层循环,[以空间换时间]
- 需要记录已经遍历过的数值和它对应的下标,借助查表实现
实现思路
遍历到数字 a 时,用 targettarget 减去 a,就会得到 b,若 b 存在于哈希表中,我们就可以直接返回结果了。若 b 不存在,那么我们需要将 aa 存入哈希表,好让后续遍历的数字使用。
大佬有动画图解,一看就懂。@demigodliu
知识点:
哈希表也被称为散列表,Hash表是一种特殊的数据结构,它同数组、栈、链表等相比较有很明显的区别,它能够快速定位到想要查找的记录,而不是与表中存在的记录的关键字进行比较来进行查找。
哈希表是基于键值对的一种数据存储结构,key值不可以重复,value可以重复,后面添加的重复的key值的时候,会把之前key值对应的value给覆盖掉,JavaScript中的对象具有天然的哈希特性。
Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值。
相比较Object而言,Map的性能在频繁增删键值对的场景下表现更好
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
let len = nums.length;
// 创建 MAP
const MAP = new Map();
/**
*Map.prototype.set(key, value)
*设置Map对象中键的值。返回该Map对象。
*/
// 由于第一个元素在它之前一定没有元素与之匹配,所以先存入哈希表
MAP.set(nums[0], 0);
for (let i = 1; i < len; i++) {
// 提取共用
let other = target - nums[i];
// 判断是否符合条件,返回对应的下标
if (MAP.get(other) !== undefined) return [MAP.get(other), i];
// 不符合的存入hash表
MAP.set(nums[i], i)
}
};
JavaScript中的对象具有天然的哈希特性
来源:@xiao_ben_zhu
const twoSum = (nums, target) => {
const prevNums = {}; // 存储出现过的数字,和对应的索引
for (let i = 0; i < nums.length; i++) { // 遍历元素
const curNum = nums[i]; // 当前元素
const targetNum = target - curNum; // 满足要求的目标元素
const targetNumIndex = prevNums[targetNum]; // 在prevNums中获取目标元素的索引
if (targetNumIndex !== undefined) { // 如果存在,直接返回 [目标元素的索引,当前索引]
return [targetNumIndex, i];
} else { // 如果不存在,说明之前没出现过目标元素
prevNums[curNum] = i; // 存入当前的元素和对应的索引
}
}
}