Topic description
Given an integer array nums
and an integer target value target
, please find the two integers whose sum is the target value target
in the array, and return their array indices .
You can assume that there will only be one answer for each input. However, the same element in the array cannot be repeated in the answer.
You can return answers in any order.
Example 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
Example 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
Example 3:
输入:nums = [3,3], target = 6
输出:[0,1]
Leetcode original title address: https://leetcode.cn/problems/two-sum/
Let's take a look at the solution...
Four schemes, progressive layer by layer, mainly based on ideas...
Option 1, direct two-layer loop to determine whether the values are equal
var twoSum = function (nums, target) {
for (let i = 0; i < nums.length; i++) {
// j=i+1即:下一项==当前项+1 因为要不断和下一项相加看看是否等于target
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] === target) {
return [i, j]
}
}
}
};
This method can be understood as a brute force method. The time complexity of two cycles is O(n) * O(n) is O(n²), which is too slow. Let's see if there is an optimization method.
Option 2, use an array to determine whether another value exists
Idea: We already know the sum of two numbers target
, and at the same time, when traversing, we can also get a number nums[i]
, as for the other number, we can subtract one from the sum The number is: otherVal = target - nums[i]
, and then look at another number otherVal
in this array, of course, you can't look directly, you have to loop again, so we can define a new one Array, append the tree in the array at a time, until it finds that there is another number in an item in the new array, that is to say, this item in the new array plus nums[i]
is exactly equal target
, in this case, the task is completed, the code is as follows:
var twoSum = function (nums, target) {
let arr = [] // 1. 定义一个数组用来另存nums数组中的数据
for (let i = 0; i < nums.length; i++) { // 2. 循环得到每一项每个 一个数
let otherVal = target - nums[i] // 3. 通过一个数 计算出 另一个数
if (arr.includes(otherVal)) { // 4. 一开始数组中肯定不包含另一个数
return [arr.indexOf(otherVal), i] // 6. 直到找到
} else {
arr.push(nums[i]) // 5. 不包含没事,那就存一份吧,方便后续匹配
}
}
};
Note that each item in the array in arr, from left to right, is consistent with the value and index of each item in the nums
array, so use arr.indexOf(otherVal)
to find The index is the index in nums
If you submit it in this way in Likou, you will find that the performance of this method is not even as good as that of brute force! Why? The reason is:arr.includes
andarr.indexOf
both methods will traverse the array, so using the array is not very good. Is it possible to use objects? Yes, let's take a look at how the object is written
Option 3, use the object to determine whether another value exists
var twoSum = function (nums, target) {
let obj = {} // 1. 定义一个对象用来另存nums数组中的数据
for (let i = 0; i < nums.length; i++) { // 2. 循环得到每一项每个 一个数
let otherVal = target - nums[i] // 3. 通过一个数 计算出 另一个数
if (Object.values(obj).includes(otherVal)) { // 4. 一开始对象中的value数组肯定不包含另一个数
// 6. values数组值中包含这个数的话,就查找这个值所对应的索引即可
let k = (Object.values(obj)).findIndex((item) => { return item == otherVal })
return [k, i]
} else {
obj[i] = nums[i] // 5. 不包含没事,就用对象存一份,对象的key是索引i,对象的value是索引项i对应的值nums[i],如此方便后续匹配
}
}
};
The idea is basically the same as the way of using the array in the second solution. It is to find out whether there is another item through the difference value. Although it can solve the problem, this way of writing is the worst way of writing among the three solutions at present, because it uses Object. values, includes, findIndex methods, so the efficiency is very low. The submission of the force buckle can barely pass, put a picture here, everyone will know
Beating 5% is basically the countdown. It's embarrassing, but it's okay, we need to think mainly
Option 4, use the Map collection to determine whether another value exists
First of all, this solution is the optimal solution, and the time and space complexity is well handled. Before talking about the solution of the Map set, let's review the basic functions of the Map set, so as to better understand the subsequent code.
Simple review of Map knowledge
let map = new Map() // new实例化一个Map对象
// 添加key value
map.set('name', '孙悟空')
map.set('age', '500')
map.set('home', '花果山水帘洞')
console.log(map.has('name'));// 是否存在key等于name的这个属性名 // true
console.log(map.get('name'));// 通过key去取其value
console.log(map.has('score'));// 是否存在key等于score的这个属性名 // true
console.log('map集合', map);
Let's take a look at the result of the 'map collection' printed out:
Look carefully, yo, this map collection looks similar to an object. We can simply understand that the Map collection is a special form of object storage. For a detailed understanding of the Map collection, you can look at the official mdn https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map
Use the Map collection to store array data
Suppose we have an array that is: let nums = [19,24,25,28,30]
- Let's see how using objects simulates storing this data
let obj = {
0:19,
1:24,
2:25,
3:28,
4:30
}
// 使用对象存储,对象的key键就是数组的下标索引,对象的value值就是数组的索引值。当然数组也可以理解为是一种特殊的对象
- Let's take another look at using the Map collection to store this array
let map = new Map()
map.set(0, 19)
map.set(1, 24)
map.set(2, 25)
map.set(3, 28)
map.set(4, 30)
console.log('map集合', map);
Take a look at printing 'map collection':
It must be reversed here. The 0th item of the array is 19. It can bemap.set(0, 19)
ormap.set(19, 0)
The specific method to use depends on the actual needs. In this topic, usemap.set(19, 0)
way is more appropriate
Well, when you see here, let's look at the specific code below, and it should be better understood with the comments.
Map set solves the problem of the sum of two numbers
var twoSum = function (nums, target) {
let map = new Map() // 1. 创建一个map集合用来存储数据
for (let i = 0; i < nums.length; i++) { // 2. 循环得到每一项每个 一个数
let otherVal = target - nums[i] // 3. 得到另外一个值
if (map.has(otherVal)) { // 4. 一开始肯定是不存在的
return [map.get(otherVal), i] // 6. 存在的话,就得到对应索引值,并返回
} else {
map.set(nums[i], i) // 5. 不存在就在map集合存一份如:map.set(19, 0)
}
}
};
This method is not bad, after all, the efficiency of the Map collection is higher. Pay attention to the distinction: 数组方式、对象方式、以及Map集合方式
their 判断是否存在、找索引
the way to distinguish, this is very important!
Summarize
Regarding the solution of the sum of two numbers, there are actually other ways. The four methods in this article are just to give you some ideas. After all, in the work, there are ideas, and the problem is basically solved 80%.
Good memory is not as good as bad writing, record it ^_^
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。