暴力双重循环就不说了,这里说用哈希表的做法。
思路就是在遍历nums数组的过程中,把nums数组的每个元素的值作为key,把元素的下标作为value,存到HashMap中,每遍历一个新元素nums[i]时,先判断与之对应的target-nums[i]是否在哈希表中,如果在,说明找到了这样的两个数,返回他们的下标,也就是他们作为key在哈希表中对应的value,如果没找到,那就将其加入到哈希表中。
class Solution {
public int[] twoSum(int[] nums, int target){
int res[] = new int [2];//用于保存结果的数组
int len = nums.length;
Map<Integer, Integer> hm = new HashMap<>(len-1);
hm.put(nums[0],0);//第一个元素放入哈希表之前,没有可以 与之比对的,所以直接放入就行了
for(int i=1;i<len;i++){
int another = target - nums[i];//对应的要找的另一个数
if(hm.containsKey(another)){//如果哈希表的键中已经存在要找的另一个数
res[0] = i;//当前正在考察的数字的下标i
res[1] = hm.get(another);//另一个数的下标,也就是他在哈希表中的value
return res;
}
hm.put(nums[i],i);//找不到对应的另外一个数,就把nums[i]和他的下标加入哈希表
}
return res;
}
}
在初始化哈希表的容量的时候,我们把其设置成len-1,是因为就算我们考虑最坏的一种情况,就是倒数第一个和倒数第二个是匹配的,然后把倒数第二个放进去后,哈希表就满了,此时我们考察倒数第一个,发现匹配,结束。所以最多只需要装n-1个键值对。
最近在学习Golang,所以这里贴两个分别用go写的暴力循环和哈希解法
暴力循环:
func twoSum(nums []int, target int) []int{
for i,x := range nums { //i,x分别是nums这个数组的下标和对应的值
for j := i+1; j < len(nums); j++ {
if x + nums[j] == target { //值相加是否等于target
return []int{i,j} //返回下标
}
}
}
return nil
}
哈希:
func twoSum(nums []int, target int) []int {
hashTable := map[int]int{}
for i,x := range nums {
if p, ok := hashTable[target - x]; ok {
return []int{p,i}
}
hashTable[x] = i //x在nums数组里面是值,在哈希表中是键
//i在nums数组里面是键,在哈希表中是值
}
return nil
}