0.题目描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
;
因为 nums[0] + nums[1] = 2 + 7 = 9
;
所以返回 [0, 1]
。
1.解题方法
1.1暴力解法
最简单的思路就是两个for循环,遍历比较。
public int[] twoSum(int[] nums, int target) {
int result[] = new int[2];
int len = nums.length;
//两层循环,进行遍历
for(int j=0;j<len-1;j++){
//内层只需要从外层后一位开始
int temp1 = nums[j];
for(int k=j+1;k<len;k++){
int temp2 = nums[k];
if(temp1+temp2==target){//符合条件,直接返回结果
result[0] = j;
result[1] = k;
return result;
}
}
}
return result;//如果找不到结果,返回没有内容的数组
}
运行结果:
分析一下,这种方法,时间复杂度是O(n^2),空间复杂度是O(1);
1.2 两次HashMap
因为涉及到寻找值和下标,使用HashMap存储键值对,查询速度快;
public int[] twoSum(int[] nums, int target){
int result[] = new int[2];
Map<Integer,Integer> map = new HashMap<Integer, Integer>();
//将数组值-数组下标作为键-值对
int len = nums.length;
for(int j=0;j<len;j++){
map.put(nums[j],j);
}
/*
再次遍历数组
若存在一个值value,使得target-value的值在map的键中存在
则返回value下标和该map键对应的值
注意:相同的下标不算
*/
for(int k=0;k<len;k++){
int result_key = target-nums[k];
if(map.containsKey(result_key)&&map.get(result_key)!=k){
result[0] = k;
result[1] = map.get(result_key);
return result;
}
}
return result;
}
结果是:
牺牲了部分空间复杂度;这种方法的时间复杂度是O(n),空间复杂度是O(n);
1.3 一次HashMap
上面的方法涉及到先把数组值和下标put到map当中,然后又取出对比,很容易想到可以将两个for循环合并;
public static int[] twoSum(int[] nums, int target){
int result[] = new int[2];
Map<Integer,Integer> map = new HashMap<Integer, Integer>();
/*
将数组值-数组下标作为键-值对
在put之前,检验已经put进去的键当中,
是否存在与当前即将put的数组值value满足target-value相等的情况
若有,返回已经put进去的键对应的值以及当前的value对应的数组下标
*/
int len = nums.length;
for(int j=0;j<len;j++){
int result_key = target-nums[j];
if(map.containsKey(result_key)){
result[0] = map.get(result_key);
result[1] = j;
return result;
}
map.put(nums[j],j);
}
return result;
}
执行情况:
这种方法的时间复杂度也是O(n),空间复杂度同样也是O(n)。