JavaScript算法:两数之和
Q:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
方法一: 暴力枚举
最容易想到的方法是枚举数组中的每一个数x,寻找数组中是否存在target-x。
当我们使用遍历整个数组的方式寻找target-x时候,需要注意到每一个位于x之前的元素都已经和x匹配过,因此不能进行重复匹配。而每一个元素不能被使用两次,所以我们只需要在x后面的元素中寻找 target-x。
代码
/**
- @param {number[]} nums
- @param {number} target
- @return {number[]}
*/
var twoSum = function (nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] === target - nums[j]) {
return [i, j]
}
}
}
};
方法二 借用hashMap:
由于暴力搜索的方法是遍历所有的两个数字的组合,然后算其和,这样虽然节省了空间,但是时间复杂度高,一般来说,为了减少时间的复杂度,需要使用空间来换,这里我们想要使用线性的时间复杂度来解决问题,也就是说,只能遍历一个数字,而另外一个数字呢,可以事先将其存储起来,使用一个Map数据结构,来建立数字和坐标之间的映射关系,由于Map是常数级查找效率,这样在遍历数组的时候,用target减去遍历到的数字,就是另外一个需要的数字了,直接在Map中查找其是否存在即可,需要注意的是,判断查找的数字不是第一个数字,比如target是4,遍历得到了一个2,那么另外一个2不能是之前的那个2,整个实现步骤为: 先遍历一遍数组,建立Map映射,然后再遍历一遍,开始查找,找到则记录index.
代码:
/**
- @param {number[]} nums
- @param {number} target
- @return {number[]}
*/
var twoSum = function (nums, target) {
let result = [];
let map = new Map();
// 遍历一遍数组, 将数组中每个值和对应的索引 做一个映射
for (let i = 0; i < nums.length; i++) {
map.set(nums[i], i);
}
// 再遍历一遍数组
for (let i = 0; i < nums.length; i++) {
// 循环每一个元素的时候 都将目标值算出来
let anotherOne = target - nums[i];
// 检查 map 中是否包含这个元素,且对应的索引不能是当前的这个索引
if (map.has(anotherOne) && map.get(anotherOne) !== i) {
// 找到则放进数组
result.push(i);
result.push(map.get(anotherOne))
break;
}
}
// 返回结果
return result
};
浙公网安备 33010602011771号