这个是 leetcode 题库的第一题,就从这个简单的开始吧。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
## 题目描述:
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
```
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
```
## 解法
看到官方的详解,一共是三种解决方法。
### 1.暴力法
这也是我唯一想到的方法,可能是我菜的原因吧。
通过遍历每个元素 xx,并查找是否存在两个值相加等于 target。

```Java
public static int[] twoSum1(int[] nums, int target) throws Exception {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target){
return new int[] {i, j};
}
}
}
throw new Exception("没有数值相加符合要求");
}
```
### 2.两遍哈希表
以下是官方的详解,只能说厉害了,真的没想到这个,通过将数组存到哈希表来获取它的索引,然后再次进行循环,判断是否有值符合要求,厉害
```
为了对运行时间复杂度进行优化,我们需要一种更有效的方法来检查数组中是否存在目标元素。如果存在,我们需要找出它的索引。保持数组中的每个元素与其索引相互对应的最好方法是什么?哈希表。
通过以空间换取速度的方式,我们可以将查找时间从 O(n)O(n) 降低到 O(1)O(1)。哈希表正是为此目的而构建的,它支持以 近似 恒定的时间进行快速查找。我用“近似”来描述,是因为一旦出现冲突,查找用时可能会退化到 O(n)O(n)。但只要你仔细地挑选哈希函数,在哈希表中进行查找的用时应当被摊销为 O(1)O(1)。
一个简单的实现使用了两次迭代。在第一次迭代中,我们将每个元素的值和它的索引添加到表中。然后,在第二次迭代中,我们将检查每个元素所对应的目标元素(target - nums[i]target−nums[i])是否存在于表中。注意,该目标元素不能是 nums[i]nums[i] 本身!
```

```Java
public static int[] twoSum2(int[] nums, int target) throws Exception {
Map<Integer, Integer> numsMap = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
numsMap.put(nums[i], i);
}
for (int i = 0; i < nums.length; i++) {
int temp = target - nums[i];
if (numsMap.containsKey(temp) && numsMap.get(temp) != i) {
return new int[] {i, numsMap.get(temp)};
}
}
throw new Exception("没有数值相加符合要求");
}
```
### 3.一遍哈希表
这个方法相当于第二个方法的进阶版吧,在第一次迭代的时候就进行判断是否有符合要求的值,没有的话程序就一直往下走,有的话就可以直接返回。
```
事实证明,我们可以一次完成。在进行迭代并将元素插入到表中的同时,我们还会回过头来检查表中是否已经存在当前元素所对应的目标元素。如果它存在,那我们已经找到了对应解,并立即将其返回。
```

```Java
public static int[] twoSum3(int[] nums, int target) throws Exception {
Map<Integer, Integer> numsMap = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int temp = target - nums[i];
if (numsMap.containsKey(temp)) {
return new int[] {i, numsMap.get(temp)};
}
numsMap.put(nums[i], i);
}
throw new Exception("没有数值相加符合要求");
}
```
## 总结
这是学习 leetcode 的第一题,也让我见识到了大神们写的代码,原来代码可以这么写,这是我的目标,干净、优雅的代码!

LeetCode 进阶之路 - 两数之和