1.两数之和:
题目:
分析:
首先我们看下要求是什么:
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
你可以按任意顺序返回答案。
从一个答案我们可以知道,不会出现输入的数组是[3,3,4],target 为 7的情况,这样我们的答案不唯一,没法操作。
好的,现在我们理清了题目的要求,那我们可以开始做题了。
两数之和——可以写成nums[i] + nums[j] = target,我们需要使用两层遍历去做吗?这样子可以写出来,但是会比较浪费时间。我们可以定义一个中间变量 temp = target - nums[i],然后去查找 temp 是否已经出现过了,如果出现过了,那不就说明我们寻找到了我们要找的两个数了吗(一个为 temp——以前存放的nums元素,另一个是现在的 nums[i] ),那我们只需要返回 temp 对应的下标 以及当前的 i即可。
那你发现了吗,这道题的整体思想,还是去寻找,是否 temp 已经出现过了!也就是我们可以用到哈希表去解决这道问题!那我们应该用说明样子的数据结构呢?数组?Set?还是Map?
我们发现,我们是通过 temp 的值去返回 temp 的 index,所以 temp 的值是一个关键码(key),而我们想要的 index 才是值!所以我们选取 map(映射)这个数据结构来解决问题。
代码:
class Solution {
public int[] twoSum(int[] nums, int target) {
// 因为是计算两数之和,所以返回的数组就是包含两个元素的数组
int[] resArr = new int[2];
// 由于需要在集合中查找元素是否存在过,所以我们使用哈希表
Map<Integer,Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++){
// 定义temp 值,初始化为目标值减去数组中的值(成立的关键在于题目中说,每种输入只会有一种答案)
int temp = target - nums[i];
// 这样,当temp作为key已经在map中存储过来,说明找到了(当前的数加上以前的数为target)
if(map.containsKey(temp)){
// 那么将temp对应的下标存放进数组中
resArr[0] = map.get(temp);
// 将当前的下标存放到索引中
resArr[1] = i;
// 退出循环
break;
}
// 若temp不再map中,说明还未找到唯一的解,可以大胆添加
map.put(nums[i],i);
}
return resArr;
}
}