这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战
前言
有人相爱,有人夜里开车看海,有人leetcode第一题都做不出来,由此可见,leetcode的题还是有分量的。今天我们就来会会它
介绍
给定一个整数数组 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) 的算法吗?
解法一
- 一看题目我们就觉得用双层for循环
so easy
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]
}
}
}
return new Error("数据nums或者target不符合规范")
};
console.log(twoSum([3,2,4],6));
思路
- 首先我们遍历数组nums,
- 再遍历一次nums,把j的默认值设为外层循环的i+1,
- 这样俩次循环的是数就不会重复了,
- 最后判断外层循环的当前值和第二次循环的当前值是否相等,相等就返回他们的下标,否则进行下一次循环
- 如果完成整个循环都没有符合条件的值,那么证明数组nums或者 target不符合规范 问题
- 这种暴力的解法
- 时间复杂度O(N2),其中n代表元素的数量,最坏的情况下,任意的俩个述职都需要匹配下才能成功
- 空间复杂度O(1)
解法二
var twoSum = function (nums, target) {
let obj = {}
for (let i = 0; i < nums.length; i++) {
if (obj[[target - nums[i]]] > -1) {
return [obj[[target - nums[i]]], i]
} else {
obj[nums[i]] = i
}
}
return new Error("数据nums或者target不符合规范")
};
console.log(twoSum([3, 2, 4], 6));
思路
- 首先创建一个空的数组
- 循环数组
nums - 通过
target-nums[i]得到剩余值 - 然后把剩余值当做
k获取对象obj中的值 - 如果值大于
-1的话,证明值存在 - 返回 当前循环的下标
i和对象obj中的值 - 如果值小于等于
-1的话 - 则把当前循环的值
num[i]当做k,值为下标,放入对象obj中 - 再次执行循环语句,直到
if条件成立或者,或者循环语句结束 注意 - 我们if判断的时候是
obj[[target - nums[i]]] > -1而不是直接这样写obj[[target - nums[i]]] - 如果采用后边的写法,那么如果
obj[[target - nums[i]]]中存着的值刚好是数组的下标0时 - 又因为
js隐式转换的原因,这个判断是不会走的
解法三
var twoSum = function(nums, target) {
let obj = Object.create(null)
for (let i = 0; i < nums.length; i++) {
if (obj[[target - nums[i]]] > -1) {
return [obj[[target - nums[i]]], i]
} else {
obj[nums[i]] = i
}
}
return new Error("数据nums或者target不符合规范")
};
console.log(twoSum([3, 2, 4], 6));
思路
- 解法三的思路和解法二基本一致
- 只是解法三在初始化的时候把
空对象替换成了Object.create(null)方法 Object.create(null)方法会创建一个无属性的对象。如图所示
解法四
var twoSum = function (nums, target) {
let map = new Map()
for (let i = 0; i < nums.length; i++) {
if (map.has(target - nums[i])) {
return [map.get(target - nums[i]), i]
} else {
map.set(nums[i], i)
}
}
return new Error("数据nums或者target不符合规范")
};
console.log(twoSum([3, 2, 4], 6));
思路
- 利用了
map数据结构的特性 - 首先通过
new Map()方法定义一个map类型的变量 - 循环
nums - 通过
target - nums[i]拿到剩余值 - 通过
map的has方法判断当前传入的k的值是否存在 - 存在的话就证明当前循环的值
+map对象中当前k刚好等于target - 那么就通过数组的形式返回他们的下标
- 如果不存在
- 那么就把当前循环的值作为
k,下标作为值赋值给map - 再次执行循环语句,直到
if条件成立或者,或者循环语句结束
写在最后
- 这篇文章虽然写的是
俩数之和的解法 - 其中也涉及了一些
js书写的注意点 - 希望你也能收获满满