两数之和

题目描述

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的 两个 整数。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例

1
2
3
4
给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

解法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public int[] twoSum(int[] nums, int target) {
int result1;
int result2;
if(nums == null){
return null;//边界条件判断
}
int len = nums.length;
for(int i=0; i<len; i++){
result1 = nums[i];
for(int j=0; j<len; j++){
result2 = nums[j];
if(i == j)
continue;//处理同一个元素被使用两次的情况
else if((result1 + result2) == target){
return new int[]{i,j};
}
continue;
}
}
return null;
}
}

这种方法通过两层遍历,称为暴力穷举,时间复杂度为O(n^2),效率极低。

解法二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public int[] twoSum(int[] nums, int target) {
if(nums == null || nums.length < 2){
return null;//边界条件
}
HashMap<Integer,Integer> map = new HashMap<>();
for(int i=0; i<nums.length; i++){
int tmp = nums[i];
Integer index = map.get(target-tmp);
if(index != null){
if(tmp == target-tmp){
return new int[]{index,i};//重复使用元素情况
}
if(i < index){//注意数组下标的输出顺序
return new int[]{i,index};
}else if(i > index){
return new int[]{index,i};
}
}
map.put(tmp,i);//后置入元素,防止被相同元素覆盖的情况
}
return null;
}
}

该方案利用了HashMap无需遍历即可查询key的特点,只进行一次遍历即可得到结果,时间复杂度也降为了O(n),但要注意处理nums存在两个相同元素时可能互相覆盖HashMap中key的情况。