目录
题目解读
关键信息解读
- 在数组中找出目标值对应的两个整数的下标
- 说明这两个整数一定存在,故其下标也一定存在
- 同一个元素在答案中不能重复出现
- 说明数组中可能存在重复元素
- 可以按顺序返回答案
- 说明即使案例的输出的顺序不同,也是正确答案
提示解读
2 <= nums.length <= 104 可以大致看出其长度范围,决定了要不要校验数据,很明显,不需要
只会存在一种有效答案说明,我们得到结果直接返回即可,不需要考虑多种情况,简化思想
实例分析
- 略
算法解读
方法一:暴力求解法
- 暴力求解法是通过一个嵌套for循环将所有存在的可能都遍历一次
- 如果发现有符合情况的直接返回
- 该算法的时间复杂度是O(N^2),空间复杂度是O(1)
方法二:查找表法
- 查找表法是通过一个已知表辅助帮我们找到对应元素
- 该算法那的时间复杂度是O(N),空间复杂度是O(N)
- 该算法可以通过BST或者是HashMap实现,这里对顺序无要求,可以用HashMap
算法思路
方法二
- 建立一个哈希表,用于存放已知数据
- 用尚未添加的数据和哈希表里面对应的数据相加,如果有对应数据,直接返回结果
- 如果没有对应数据,添加当前数据
算法图解
注意:key表示数值,value表示对应数值的下标
代码实现与分析
class Solution {
public HashMap<Integer,Integer> memo;
public int[] twoSum(int[] nums, int target) {
// 用于记录数组长度(写习惯了)
var n = nums.length;
// 对一个你的哈希表,需要指明其长度,避免底层扩容带来的时间损耗
// 大小设立为n - 1,原因请看解析一
HashMap<Integer,Integer> memo = new HashMap<>(n - 1);
// 由于哈希表一开始什么元素都没有,不可能找到其对应元素,直接放下去即可
// 注意:key和value的值
memo.put(nums[0],0);
// 从下标为1开始遍历
for (int i = 1; i < n; i++) {
// 对应的元素就是相减的元素,如符合条件,直接返回
if (memo.get(target - nums[i]) != null) {
return new int[] {i,memo.get(target - nums[i])};
}
// 添加到集合中
memo.put(nums[i],i);
}
// 这里写啥都无所谓,反正跟执行不到这里
return null;
}
}
解析一:
从算法图解中可知,算法最坏情况下,会往哈希表里面存放N-1个元素,为什么不是N呢,因为最后一个元素去取的时候一定会在哈希表里面取到其对应的元素,题目中明示了一定有两个元素可以达到target
算法总结
当我们遇到取数据的时候,一般可以采取查找表法
不定期输出算法内容,随缘输出,你别关注啦