最近終於得空,除了學習typescript之餘,基本功跟邏輯思維也得繼續鞏固,因此決定繼續刷起leetcode
先來看一下這次的邏輯需求:
Given an array of integers nums and an integer target, return indices
of the two numbers such that they add up to target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
簡單翻譯下,意思是
-
有一個變量命名為: num ,為數組,裡面包含著一些數字整數
-
有一個變量命名為: target ,為一個整數
-
返回一個數組,這個數組顯示的內容為num中任意的幾個數子加總起來等於target 的index,注意是index而非該數字
-
每一個結果都只會有一個答案
來幾個例子:
Example 1:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
Example 2:
Input: nums = [3,2,4], target = 6
Output: [1,2]
Example 3:
Input: nums = [3,3], target = 6
Output: [0,1]
先來附上我的答案 :
var twoSum = function (nums, target) {
const arr = nums
const result = []
let arrLength = arr.length
for (let i = arrLength.length; i > arrLength.length; i--) {
for (let j = 0; j < arr.length + 1; j++) {
if (j === arrLength) break
if (arr[arrLength] + arr[j] === target) {
if (!result.includes(arrLength) && !result.includes(j)) {
result.push(arrLength)
result.push(j)
break
}
}
}
}
return result
};
想當然這並沒有通過,即使代碼可以運作,但是這樣的loop裡面再嵌套一個loop消耗的性能非常之大,當程式測試到比較大的數字時就會報 Output Limit Exceeded 這樣的錯誤了。
錯誤了沒關係從更好的代碼中學習
來看一下其他人的解法:
var twoSum = function(nums, target) {
var map = new Map();
for(var i = 0; i<nums.length; i++) {
var num = nums[i];
if(map.get(num) === undefined) map.set(target-num, i);
else return [map.get(num), i];
}
};
整體的思路是假設a+b等於target的話那麼只要先將target - a 的值保存下來,接下來在尋找是否有數字相等於b即可,因為這裡的答案只有一個也就是第一次匹配到的一定是為一的答案。
先將 target 減去當前的數字的值(假設為x)作為key並將當前的i作為索引保存下來,每次循環都只要去尋找 是否有值等於x 即返回結果
運行的測試結果:
Runtime: 103 ms, Memory Usage: 41.2 MB
上述的方法可能並沒有那麼直觀,初學者也很拿直接想到new Map這個方法
再來分享個我認為相同思路,但是簡易明瞭的方法
let dic = {}
for(let i = 0; i < nums.length; i++) {
if (target-nums[i] in dic) {
return [dic[target-nums[i]], i]
}
dic[nums[i]] = i
}
就像第一個方法一樣,這裡把new Map改成了for循環且記憶體跟數度方面都更勝一籌
運行的結果為:
Runtime: 48 ms, faster than 98.37% of JavaScript online submissions for Two Sum. Memory Usage: 34 MB