【算法-初级-数组】两数之和(JavaScript实现)

161 阅读1分钟

【算法-初级-数组】两数之和(JavaScript实现)

博客说明

文章所涉及的部分资料来自互联网整理,当然还有自己个人的总结和看法,分享的目的在于共建社区和巩固自己。引用的资料如有侵权,请联系本人删除!幸好我在,感谢你来!

算法说明

语言只是实现算法的一种手段,思路才是最为重要的。

如果有多种解法的话,只选一种语言作为解答对比。

如果单独将某一种算法的话,会以多种语言实现,对比语言的特性。

😎因为多对多的话,篇幅会拉的比较大,影响观看体验!

题目

地址

1. 两数之和

题目说明

给定一个整数数组 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) 的算法吗?

思路

思路?第一题嘛!

思路那还不是暴力开头。

首先要贴出一条评论,这正是第一题的尴尬哈!

image-20211228233907235

暴力解法

思路

双层遍历,一层一层找,指定一个x,直到找到target - x的值就好了。

JavaScript

代码

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
    const n = nums.length;
    for(let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++){
            if(nums[i] === target - nums[j]) {
                return [i,j]
            }
        }
    }
    return []
};

复杂度分析

时间复杂度:O(N^2),其中 N 是数组中的元素长度。

空间复杂度:O(1)。

改进

可以使用js数组的indexOf方法找到,防止遇到重复的值curIndex !== i过滤一下。

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
    const n = nums.length;
    for(let i = 0; i < n; i++) {
        const curIndex = nums.indexOf(target - nums[i])
        if(curIndex !== -1 && curIndex !== i) {
            return [i, curIndex]
        }
    }
    return []
};

看结果

image-20211229000759618

优化了个寂寞,时间复杂度并没有减少!

哈希表

思路

看到重复的元素一下想到了哈希表

想一下,把题目转变一下,它是要求两数之和,那是不是可以拿结果去减去一个值,那么根据题意得到数必定是还是在数组当中的。可以减少一次遍历。

JavaScript

代码

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
    const n = nums.length;
    const map = new Map()
    for(let i = 0; i < n; i++) {
        const curIndex = target - nums[i]
        if(map.has(curIndex)) {
            return [map.get(curIndex), i]
        }else {
            map.set(nums[i], i)
        }
    }
    return []
};

解析

这样一下来大大减少了时间复杂度。

时间复杂度超98的用户可还行?

空间复杂度:你说啥?

image-20211229001630029

总结

在双层遍历的时候,可以考虑降低遍历的次数,以便提高时间效率,降低时间复杂度。

感谢

万能的网络

放在LeetCode上的题解

以及勤劳的自己,个人博客GitHub测试GitHub

公众号【归子莫】,小程序【小归博客】

如果你感觉对你有帮助的话,不妨给我点赞👍吧,持续关注也行哈!