[路飞]_程序员必刷力扣题: 两数之和

279 阅读1分钟

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

两数之和

力扣链接

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]

示例 2:

输入: nums = [3,2,4], target = 6
输出: [1,2]

示例 3:

输入: nums = [3,3], target = 6
输出: [0,1]

提示:

2 <= nums.length <= 104 -109 <= nums[i] <= 109 -109 <= target <= 109 只会存在一个有效答案 进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?

双重遍历

思路

这个题目我们很快就可以想到双循环暴力查找。

这就是一个空间换时间的例子

第一层循环来获取第一个值

第二层循环用来寻找是否存在另一个值可以和nums[i]相加等于target

这里有一个小的优化点,在第二层循环的时候不需要再从头循环了,因为第一层循环其实已经发现之前的值都不存在正确答案了。所以直接从i后面开始继续往后找。

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]
            }
        }
    }
};
var nums = [2,7,11,15], target = 9
console.log(twoSum(nums,target))

哈希表

思路

另一种思路就是用空间换时间。

我们可以再第一次遍历的时候吧所有的值都记录在哈希表中,接下来再去查找元素的时候就不需要在遍历了,可以直接在哈希表中查找,对应的key值存不存在,有没有值就可以了

第二次遍历第一步,拿到nums[i]作为第一个数

然后target-nums[i]得到第二个值

再去map表中查找存不存在

这里需要注意的点:

  • nums中值不唯一,所以map表中我们需要用数组来保存值的下标
  • 要注意两数之和的两个下标不能为同一个值。如果nums[i] * 2 = target;则map[nums[i]]的length大于等于2则满足条件,否则不满足
var twoSum = function(nums, target) {
    var map = {}
    for(let i=0;i<nums.length;i++){
        if(map[nums[i]]===undefined){
            map[nums[i]] = [i]
        }else{
            map[nums[i]].push(i)
        }
    }
    console.log(map)
    for(let i=0;i<nums.length;i++){
        var secNum = target - nums[i]
        if(secNum === nums[i]){
            if(map[secNum].length>1){
              return [i,map[secNum][1]]
            }else{
              continue
            }
        }
        if(map[secNum]){
            return [i,map[secNum][0]]
        }
    }
};
var nums = [3,2,4], target = 6
console.log(twoSum(nums,target))