# 0001. Two Sum ## [題目:](https://leetcode.com/problems/two-sum/) 哪兩個數相加等於`target`,回傳兩數所在的`index`。 最少且只會有一筆正確的答案。同一元素不能重複使用兩次。 > 測試資料: > > [2,7,11,15] 9 [3,2,4] 6 [3,3] 6 > > 輸出: [0,1] [1,2] [0,1] ## 思路一:暴力法、窮舉法 用雙迴圈把每種可能都加起來比較一次 ```go= func twoSum(nums []int, target int) []int { for i, n1 := range nums{ for j, n2 := range nums{ if i != j && n1 + n2 == target{ return []int{i,j} } } } return nil } ``` ```go= func twoSum(nums []int, target int) []int { for i := 0; i < len(nums); i++{ for j := i+1; j < len(nums); j++{ if nums[i] + nums[j] == target{ return []int{i, j} } } } return nil } ``` ## 思路二:用map記下這數字的索引位置 第一次迴圈:用map記下這數字的索引位置 第二次迴圈:再尋一次nums,尋找有無此元素的補數,有則讀出該補數的索引位置 ```go= func twoSum(nums []int, target int) []int { var m = map[int]int{} for i, n := range nums{ m[n] = i // 記下這數字的索引位置 // 因為一定會有一組解,數值相同的被後面值的索引蓋過去沒影響 } for i, n := range nums{ if j, ok := m[target-n]; ok && i != m[target-n]{ // map中的key(target-n)有值,且元素不重複 return []int{i, j} } } return nil } ``` > 測試資料: > [2,7,11,15], 9 > > map的樣子: key value [2] = 0 [7] = 1 [11] = 2 [15] = 3 ## 思路三:用map記下互補數字的索引位置 和思路二大同小異,只是又能省去一個迴圈 只用一次回圈,用map記錄下互補數(可以與本元素組成目標值的另一個數)的索引位置 在依序讀數字進來的當下,看一下map中目前有無互補數, 有則直接返回,沒有的話再加進map中,也能省去判斷元素重複使用的問題 ```go= func twoSum(nums []int, target int) []int { var complement = map[int]int{} // complement 記錄此元素的補數(與target的差) for i, n := range nums{ if j, ok := complement[n]; ok{ return []int{i, j} } complement[target-n] = i // key:補數 ; value:補數所在位置的索引 } return nil } ``` > 測試資料: > [2,7,11,15], 9 > > map的樣子: key value [7] = 0 [2] = 1 [-2] = 2 [-6] = 3 這解法真是腦洞大開啊!