LeetCode 之 JavaScript 解答第一题 —— 两数之和(Two Sum)

Time:2019/4/1
Title: Two Sum
Difficulty: simple
Author: 小鹿
公众号:一个不甘平凡的码农。

题目一:Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would have exactly one solution, and you may not use the same element twice.

问题:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1]
复制代码

Solve:

▉ 法一:暴力破解法

算法思路:用目标值减去数组中的某一个数值,查找差值是否在数组中存在。

/**
 * 步骤:
 * 1)外循环:target 值要一一减去数组中的元素,记录差值
 * 2)内循环:拿着差值去数组中比较判断是否存在
 * 3)如果存在:返回两个元素的下标
 * 4)如果不存在:继续遍历
 *
 * 性能分析:
 * 1)时间复杂度分析:两层 for 循环,所以时间复杂度为 O(n^2)
 * 2)空间复杂度分析:不需要额外的空间,所以空间复杂度为 O(1)
 */
var twoSum = function(nums, target) {
    for(let j = 0;j < nums.length; j++){
        subtract = target - nums[j];
        for(let i = 0;i < nums.length; i++){
            if(nums[i] == subtract && i !== j){
                return [j,i]
            }else{
                continue;
            }
        }
    }
    return false;
};
//测试
const nums = [2,7,11,15];
console.log(twoSum(nums,26));
复制代码
▉ 法二:两遍哈希表

算法思路:先遍历数组将下标对应的元素存到散列表,然后同目标值减去的值去散列表中查看是否存在。

/**
 * 步骤:
 * 1)遍历数组数据,将根据下标和元素值存放到散列表中。
 * 2)目标值减去数组元素差值并在散列表中查找。
 * 3)如果存在,返回两元素的下标。
 * 4)不存在继续遍历
 *
 * 性能分析:
 * 1)时间复杂度分析:随机访问的时间复杂度为O(1),但是需要遍历所有数据,所以时间复杂度为 O(n)。
 * 2)空间复杂度分析:需要额外的 n 大小的空间存储散列表,空间复杂度为 O(n)。
 */
var twoSum = function(nums, target) {
    var map = new Map();
    for(let i = 0;i < nums.length; i++){
        map.set(nums[i],i)
    }
    for (let j = 0; j < nums.length; j++) {
        substra = target - nums[j];
        if(map.has(substra) && map.get(substra) !== j){
            return [j,map.get(substra)]
        }
    }
}

// 测试
const nums = [2,7,11,15];
console.log(twoSum(nums,9));
复制代码
▉ 法三:一遍哈希表

算法思路:遍历目标值减去数组元素的差值同时判断该值在散列表中是否存在差值,如果存在,则返回;否则将数据加入到散列表中。

/**
 * 步骤:
 * 1)遍历目标值减去数组元素的差值同时判断该值在散列表中是否存在差值
 * 2)存在该差值,返回该元素下标
 * 3)不存在,将该差值存储到散列表中继续遍历。
 *
 * 性能分析:
 * 1)时间复杂度分析:随机访问的时间复杂度为O(1),但是需要遍历所有数据,所以时间复杂度为 O(n)。
 * 2)空间复杂度分析:需要额外的 n 大小的空间存储散列表,空间复杂度为 O(n)。
 */
var twoSum = function(nums, target) {
    var map = new Map();
    for(let i = 0;i < nums.length; i++){
        substra = target - nums[i];
        if(map.has(substra)){
            return [i,map.get(substra)]
        }
        map.set(nums[i],i)
    }
    return false;
}

// 测试
const nums = [2,7,11,15];
console.log(twoSum(nums,26));
复制代码
▉ 总结:

1、涉及到查找、判断是否存在,相关的数据结构有散列表、平衡二叉树、二分查找、跳表、二叉查找树。

2、使用数据结构的时候注意适用条件

3、注意对时间复杂度、空间复杂度的优化策略。



欢迎一起加入到 LeetCode 开源 Github 仓库,可以向 me 提交您其他语言的代码。在仓库上坚持和小伙伴们一起打卡,共同完善我们的开源小仓库! Github:https://github.com/luxiangqiang/JS-LeetCode
欢迎关注我个人公众号:「一个不甘平凡的码农」,记录了自己一路自学编程的故事。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值