# 寻找两数之和算法揭秘

·  阅读 89

## 示例

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

## 思路一

A really brute force way would be to search for all possible pairs of numbers but that would be too slow. Again, it's best to try out brute force solutions for just for completeness. It is from these brute force solutions that you can come up with optimizations.

### 代码

class Solution {
public int[] twoSum(int[] nums, int target) {
// 双重循环 循环极限为(n^2-n)/2
for(int i = 0; i < nums.length; i++){
for(int j = nums.length - 1; j > i; j --){
if(nums[i]+nums[j] == target){
}
}
}
}
}

## 思路二

So, if we fix one of the numbers, say

x, we have to scan the entire array to find the next number y which is value - x where value is the input parameter. Can we change our array somehow so that this search becomes faster?

### 代码

class Solution {
public int[] twoSum(int[] nums, int target) {
List<Integer> list = new ArrayList<>(nums.length);
for(int i = 0; i < nums.length; i++){
if(list.contains(nums[i])){
}
}
}
}

## 思路三

The second train of thought is, without changing the array, can we use additional space somehow? Like maybe a hash map to speed up the search?

### 代码

class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> hash = new HashMap<>(nums.length);
for(int i = 0; i < nums.length; i++){
if(hash.containsKey(nums[i])){
}
// 将数据存入 key为补数 ，value为下标
hash.put(target-nums[i],i);
}
}
}

## 总结

• 思路一: 不用我说了吧，就是双层循环，没有可解释的，大部分人的做法。
• 思路二: 想法很简单，就是我们把目标值和你循环的值做差，然后存在相差的list，然后下一个循环的值如果在差值list里就寻找到了这个两个值。看似是时间复杂度是O(n),如果你看过list的源码你会发现，你想想的只是想象，我们来看一看思路二程序的源码部分
//list.contains(nums[i])
//list.indexOf(nums[i])
public boolean contains(Object o) {
return indexOf(o) >= 0;
}

public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}

 for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
for (int z = 0; z <= i; z++) {

}
}
}

$1^2+2^2+3^2+...+n^2=n(n+1)(2n+1)/6$ 哈哈，是不是发现那个耗时是正常的。有些时候看似简单代码往往最致命。那就有人问hash.containsKey(nums[i])那它为什么这么快，这就需要看看HashMap源码了。

• 思路三: HashMap根据key找value时间复杂度是O(1) 所以我们就用HashMap，下面我们来看看hash.containsKey(nums[i])的源码
public boolean containsKey(Object key) {
return getNode(hash(key), key) != null;
}

public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}

final Node<K,V> getNode(int hash, Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k))))
return first;
if ((e = first.next) != null) {
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);
}
}
return null;
}