> For the complete documentation index, see [llms.txt](https://kerasnoone.gitbook.io/garnet/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kerasnoone.gitbook.io/garnet/suan-fa/shu-zu/1-liang-shu-zhi-he.md).

# \[1]\[简单]\[哈希] 两数之和

## 题目描述

[1. 两数之和](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]
```

## 解题思路

在$$O(N)$$时间内求解. 我们可以先遍历一遍列表, 得到每个数对应的索引组成的字典. 然后再从头到尾遍历一遍数组, 对于每个数字, 判断互补的那个数字是否在字典中, 在就找到了对应的两个数.

或者边遍历, 边判断. 对于每个数字, 我们要找的是它互补的那个数字, 因此在遍历过程中, 对于数字`numbers[i]`, 我们将`target-numbers[i]`存放到字典中, 这样如果遍历到`target-numbers[i]`, 就可以直接找到`numbers[i]`对应的索引. 注意两点:

* 可能存在多个相等的数字, 因此`key`对应的值是一个`list`, 将所有符合的`i`都放进去
* 某个位置的数只能使用一次, 为防止使用两次的情况, 判断结果时, 应排除两个数字`i`相同的情况

```python
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        mapping = dict()
        for i, n in enumerate(nums):
            op = target - n
            if op in mapping:
                op_list = mapping[op]
                t_list = [t for t in op_list if t != i]
                if len(t_list) > 0:
                    return [t_list[0], i]

            if n in mapping:
                mapping[n].append(i)
            else:
                mapping[n] = [i]
```
