题目
给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例
1 | 给定 nums = [2, 7, 11, 15], target = 9 |
思路
暴力
最简单的一种思路,两层循环,两两相加后与target比较。但是循环的起点不同,第一个元素和后面的每个元素进行比较,第二个元素也是和它之后的元素进行比较,所以外层的循环起点为0,内层的循环起点则是由外层决定,若外层为i,则内层循环起点为i+1,这样也可以保证,不重复利用数组中同样的元素。
1 | class Solution { |
哈希表
暴力方法之所以要循环两次,是因为我们需要找两个数的下标,采用哈希表的方法,在循环过程中存储下标,可以省去嵌套一次循环,但是找结果的方式与暴力方式不太一样。
1 | class Solution { |
上面的暴力方法,是从前往后找另外一半,找到立刻返回,比如
1 | int nums[] = new int[]{2, 7, 11, 15}; |
若target目标值为17,执行过程:
i,j | 计算结果 | 是否匹配 |
---|---|---|
0,1 | 9 | NO |
0,2 | 13 | NO |
0,3 | 17 | YES |
若是用哈希表的方式,可以理解为从当前循环点往前找另外一半,利用的是2+3=5,3+2=5,加法的交换律,不管从前往后还是从后往前,都是OK的。
执行过程:
i | 是否匹配 | 单次循环结束后map |
---|---|---|
0 | NO | (2, 0) |
1 | NO | (2, 0) , (7,1) |
2 | NO | (2,0) , (7,1) , (11,3) |
3 | YES |
总结
- 某些场景下,暴力方式可能速度更快,但是第二种方式整体时间复杂度低。
- 第二种采用HashMap 的方式,当然也可以采用其他存储数值和下标的式。