题干
给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
示例
示例1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例3:
输入:nums = [3,3], target = 6
输出:[0,1]
题解
(一)暴力枚举法
时间复杂度:O(n^2) 空间复杂度:O(1)
思路及算法
枚举数组中的每一个数x,寻找数组中是否存在target-x。
当我们使用遍历整个数组的方式寻找target-x时,需要注意到每一个位于x之前的元素都已经和x匹配过,所以不需要再次进行匹配。而每一个元素不能被使用两次,所以我们需要在x的后面寻找元素target-x。
代码实现
class Solution{
public int [] twoSum(int [] nums, int target){
int n = nums.length;
for(int i =0; i < n; i++){
for(int j = n+1; j < n; j++){
if(nums[i] +nums[j} == target)
renturn new int[]{i,j};
}
}
return new int[0];
}
(二)哈希表
时间复杂度0(n) 控件复杂度O(n)
思路及算法
注意到方法一的时间复杂度较高,是因为寻找target-x的时间复杂度较高。所以我们需要一种更优秀的方法,来快速寻找数组中是否存在目标元素。如果存在,就找出它的索引。
使用哈希表,可以讲寻找target-x的时间复杂度降低,由O(N)降到O(1)。
这样,我们创建一个哈希表,对于每一个x,我们首先查询哈希表中是否存在target-x,如果没有,则将键和值都插入到哈希表中,如果有,则直接配对。
代码实现
class Solution{
pubic int twoSum(int[] nums, int target){
Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>(); //Map<Integer, Integer>把每个元素作为key,每个索引作为value
for(int 1 = 0; i < nums.length; i++){
if(hashtable.containsKey(target - nums[i]){
//containsKey()方法用于检查给定对象是否为键元素
return new int[]{hashtable.get(target-nums[i]), i}
//get()方法用于返回与此哈希表中给定键元素关联的值
hashtable.put(nums[i],i);//如果没有找到,则把当前的键值对放进hashtable表中
}
return new int[0];
}
}