关于LeetCode更多详细的代码,请参考https://github.com/Crazykev/Leetcode
题解
比较简单的题目,找一个数组中特定的两个数相加为目标数,如果固定一个数,再用目标数减去当前数,那么我们只需要找这个补足数是否存在于数组中便可以了。
思路1:
用暴力枚举遍历列表中所有元素,对于每一个元素,遍历其后的所有元素,判断它们相加是否等于目标数,如果是则输出。这样的算法时间复杂度是O(n^2),空间复杂度O(1),简单直接。
代码
思路2:
如分析中所言,遍历一遍数组元素的操作无法避免,我们需要寻找一个方式来更快地查询到补足数,思路1中使用的方式是线性遍历所有元素,这是最慢的方式了。现在我们考虑查询最快的速度O(1)级别的,常见的便是hash表了。遍历数组第一遍将数组元素映射到一个hash表中,在第二遍查询的时候只需要去hash表里面查补足数是否存在即可(这里需要排除查到的补足数是自身的情况)。
其实这里我们可以直接遍历一次数组就完成,一边构建hash表,一边查询补足数,也不会出现漏解的可能(想象一下思路1的逆序查询就行了)。而且如果先查询补足数,再插入hash表的情况下,这么做有一个好处是不用再去纠结查到的补足数是否为自身了。
代码
代码
golang
思路1
func twoSum(nums []int, target int) []int {
numLen := len(nums)
for i, num := range nums[:numLen-1] {
tmpT := target - num
for j, numb := range nums[i+1:] {
if numb == tmpT {
return []int{i, j+i+1}
}
}
}
return nil
}
思路2
golang中map实现便是基于hash表,直接用比较省事,这里也可以自己实现。我造的轮子并没有减少实际运行时间,golang版最终时间为9ms。不知更快的大神是怎么做到的。
func twoSum(nums []int, target int) []int {
numMap := make(map[int]int)
for i, num := range nums {
if index, ok := numMap[target-num]; ok {
return []int{index, i}
}
numMap[num] = i
}
return nil
}