给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
暴力解
最简单的办法两层for循环即可,当然还有更优解,利用哈希算法
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]+nums[j]==target){
return [i,j]
}
}
}
};
算法使用了双重循环,时间复杂度为,其中 n 是数组的长度。具体地,对于数组中的每个元素,都需要遍历一遍剩余的元素进行比较
哈希解
var twoSum = function(nums, target) {
let n=nums.length; //获取数组长度n
let map=new Map(); //创建Map对象
for(let i=0;i<n;i++){ //遍历数组元素
const yushu=target-nums[i] //计算目标值与当前元素的差
if(map.has(yushu)){ //如果差在之前的元素中出现过
return [map.get(yushu),i] //返回之前元素的下标和当前元素的下标
}else{
map.set(nums[i],i) //将当前元素及其下标存入Map对象中
}
}
return [] //如果遍历结束后没有符合要求的结果,则返回空数组
};
这段代码实现的是在给定数组中找到两个数,使得它们的和为目标值,并返回这两个数在数组中的索引。但该算法与前面提到的双重循环的算法不同,它使用了哈希表,时间复杂度为 O(n),其中 n 是数组的长度。
具体地,算法首先遍历一遍数组,将每个元素及其下标存入一个哈希表(Map对象)中。接着再遍历一遍数组,在遍历过程中计算目标值与当前元素的差,然后在哈希表中查找是否存在这个差值,如果存在,则说明当前元素与之前的某个元素的和为目标值,直接返回这两个元素的下标即可。如果遍历结束后仍未找到符合要求的结果,则返回空数组。
因为该算法只需要遍历数组两次(第一次遍历时需要将元素存入哈希表中),而哈希表的查询操作时间复杂度为O(1),因此总时间复杂度为 O(n)。相对于时间复杂度为 的双重循环算法,这个算法的效率更高,特别是对于输入规模非常大的情况下效果更为明显。