No1.两数之和

题目描述

No1.两数之和 ——中文站原站

难度:简单

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

1
2
3
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

1
2
输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

1
2
输入:nums = [3,3], target = 6
输出:[0,1]

提示:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案

进阶:你可以想出一个时间复杂度小于 $O(n^2)$ 的算法吗?


题解

暴力遍历

一个数组找出2个满足一定条件的数,嵌套循环,遍历完所有的可能性,判断满足的条件。

时间复杂度:$O(N^2)$,空间复杂度:$O(1)$

HashMap存值

上面的暴力解法,将大量的时间都用在遍历之前已经判断过的值上,要降低时间复杂度必然不能遍历无效结果。

我们可以在只遍历一次数组,在遍历每一个值时,将值和其下标存在HashMap中,K为值,V为下标,并从之前已经储存在HashMap的值中寻找是否存在满足条件的值,即为target与当前值的差,如果没有,继续往下遍历,如果存在,取出它的下标和当前值的下标得到结果。

leetcode上有评论提到了哈希碰撞会导致查找差值的时间复杂度不会是$O(1)$,当把相同的值放进

由于HashMap的查找时间复杂度为$O(1)$,我们只遍历了数组一次,所以整个的时间复杂度为$O(N)$。如果我们使用数组,链表来存值,每次查找需要$O(N)$时间复杂度,最终同样是$O(N^2)$的时间复杂度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution{
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> hashMap = new HashMap<Integer,Integer>();
for(int i=0;i<nums.length;i++){
int complement = target-nums[i];
if(hashMap.containsKey(complement)){
int j = hashMap.get(complement);
return new int[] {i,j};
}
hashMap.put(nums[i],i);
}
return new int[]{};
}

}