【算法-初级-数组】两数之和(JavaScript实现)
博客说明
文章所涉及的部分资料来自互联网整理,当然还有自己个人的总结和看法,分享的目的在于共建社区和巩固自己。引用的资料如有侵权,请联系本人删除!幸好我在,感谢你来!
算法说明
语言只是实现算法的一种手段,思路才是最为重要的。
如果有多种解法的话,只选一种语言作为解答对比。
如果单独将某一种算法的话,会以多种语言实现,对比语言的特性。
😎因为多对多的话,篇幅会拉的比较大,影响观看体验!
题目
地址
题目说明
给定一个整数数组 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) 的算法吗?
思路
思路?第一题嘛!
思路那还不是暴力开头。
首先要贴出一条评论,这正是第一题的尴尬哈!
暴力解法
思路
双层遍历,一层一层找,指定一个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 []
};
看结果
优化了个寂寞,时间复杂度并没有减少!
哈希表
思路
看到重复的元素一下想到了哈希表。
想一下,把题目转变一下,它是要求两数之和,那是不是可以拿结果去减去一个值,那么根据题意得到数必定是还是在数组当中的。可以减少一次遍历。
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的用户可还行?
空间复杂度:你说啥?
总结
在双层遍历的时候,可以考虑降低遍历的次数,以便提高时间效率,降低时间复杂度。
感谢
万能的网络
公众号【归子莫】,小程序【小归博客】
如果你感觉对你有帮助的话,不妨给我点赞👍吧,持续关注也行哈!