题目
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?
来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/tw…
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
- 查找表法
使用一个hash表记录遍历过的数值(Key)和其对应的下标(Value),然后遍历数组第
i个元素的时候,去hash表中找Key为target - nums[i]的记录,如果有,则该记录对应Value和当前下标i的两个数字之和为target。
该解法是用空间换时间,通过申请数组nums长度的hash表,只需要遍历数组一遍,算法复杂度为O(n)。
查找表法的具体实现有两种:哈希和平衡二叉搜索树,由于这里不需要维护顺序性,采用哈希即可。
具体算法
public int[] twoSum(int nums[], int target) {
int len = nums.length;
// 初始化的时候尽量在构造中写容量,避免扩容带来的效率问题
// 用于记录遍历过的数值(key)和下标(value)
Map<Integer, Integer> hash = new HashMap<>(len - 1);
// 因为第0个数在空表中一定不会找到对应下标,直接将其放入
hash.put(nums[0], 0);
// 循环从nums第二个数字开始
for (int i = 1; i < len; i++) {
// 如果hash表中有对应的key就找到和为target的两个数
if (hash.containsKey(target - nums[i])) {
return new int[]{i, hash.get(target - nums[i])};
} else {
// 否则就将当前遍历的数值作为key下标作为value存入hash中
hash.put(nums[i], i);
}
}
// 如果程序执行到这里说明该数组中没有两数和为target,抛出异常
throw new IllegalArgumentException("No Two Sum Solution");
}