[LeetCode] 1.Two Sum 两数之和分析以及实现 (golang)
题目描述:
/*
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
*/
这道题给了我们一个数组,还有一个目标数target,让我们找到两个数字,使其和为target。首先想到的就是暴力搜索,遍历所有的组合项,获得结果,思路比较简单,代码如下:
func func1(s []int, tag int) []int { for i := 0; i < len(s)-1; i++ { for j := i + 1; j < len(s); j++ { if s[i]+s[j] == tag { return []int{i, j} } } } return nil }
这个算法的时间复杂度是O(n^2)。虽然节省了空间,但是时间复杂度高。尝试用空间换时间,使用一个HashMap,建立数字和其坐标位置之间的映射,在遍历数组的时候,用target减去遍历到的数字,就是另一个需要的数字了,直接在HashMap中查找其是否存在即可,那么代码就可这样写:
func func2(s []int, tag int) []int { hash := make(map[int]int) for i := 0; i < len(s); i++ { hash[s[i]] = i } for i := 0; i < len(s); i++ { temp := tag - s[i] if _, ok := hash[temp]; ok { if hash[temp] == i { continue } return []int{i, hash[temp]} } } return nil }
这个算法的时间复杂度是O(n)。再想想,代码好像可以更加简洁一些,把两个for循环合并成一个:
func func3(s []int, tag int) []int { hash := make(map[int]int, len(s)) for k, v := range s { if j, ok := hash[tag-v]; ok { return []int{j, k} } hash[v] = k } return nil }
这样看起来就比较舒服ok了,完整的贴上来,运行一下试试吧。
package main import ( "fmt" ) func main() { nums := []int{2, 7, 11, 15} target := 9 s := func1(nums, target) //s := func2(nums, target) //s := func3(nums, target) fmt.Printf("nums[%d]+nums[%d]=%d+%d=%d\n", s[0], s[1], nums[s[0]], nums[s[1]], target) fmt.Printf("return [%d,%d]", s[0], s[1]) } //暴力破解 时间复杂度O(n^2) func func1(s []int, tag int) []int { for i := 0; i < len(s)-1; i++ { for j := i + 1; j < len(s); j++ { if s[i]+s[j] == tag { return []int{i, j} } } } return nil } //用map辅助查找 时间复杂度O(n) func func2(s []int, tag int) []int { hash := make(map[int]int) for i := 0; i < len(s); i++ { hash[s[i]] = i } for i := 0; i < len(s); i++ { temp := tag - s[i] if _, ok := hash[temp]; ok { if hash[temp] == i { continue } return []int{i, hash[temp]} } } return nil } //优化一下,把两个for循环合并成一个 func func3(s []int, tag int) []int { hash := make(map[int]int, len(s)) for k, v := range s { if j, ok := hash[tag-v]; ok { return []int{j, k} } hash[v] = k } return nil }