题目描述:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值的那两个整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。你可以按任意顺序返回答案。
暴力解法:
public static int[] twoSum(int[] nums, int target) { int first = 0,end = 0; for (int i = 0; i < nums.length; i++) { for (int j = 0; j < nums.length; j++) { // 两层for循环 if(nums[i] + nums[j] == target){ // 一旦找到了 first = j; // 拿出第一个的下标 end = i; // 拿出第二个的下标 break; } } } int[] result = {first,end}; // 两个下标放入结果数组 return result; // 返回结果数组 }
该题难度描述为简单,因为非常容易想到使用两层暴力for循环,就能解出来,但这样时间复杂度就是O(n^2),消耗时长。
想法:既然有元素值的比较以及下标的获取这样两者对应关系下的操作,就不难想到双列组合map,而map集合最经典的应用就是hashMap,且由于需要遍历元素值,hashMap在理想状态(无hash冲突)时查找元素时间复杂度是O(1),明显可以提高速度。
思路:我们可以创建一个hashMap用来存储nums数组元素值(key)以及对应的下标(value),我们遍历数组,做两个操作,一个是按格式存入键值对,一个是将target减去正遍历到的元素值,作为一个key值查找map里是否已经存入该key值,如果有,那么这个key值对应的value值和正遍历的值的数组下标组成的数组就是我们需要的输出结果。
注意:因为题目并未限制元素不可以重复,且hashMap如果有重复key值,那么不会存在两个key,而是后来的value值替换掉原来的value值,为了保证特殊情况下两个都取出来或者说被替换前的取出来,我们放入结果数组里的后来者应该是数组元素对应的下标,而不是放进去之后取出来的value。(这样就在替换前就拿到结果了)
hashMap解法:
private static int[] twoSum(int[] nums,int target) { int[] result = new int[2]; // 创建结果数组 // 新建一个hashMap HashMap<Integer,Integer> map = new HashMap<>(); // 遍历数组 for (int i = 0; i < nums.length; i++) { if(map.containsKey(target - nums[i])){ // 因为结果是唯一,所以一旦存在即两个都存在 // 输出数组 // 此处注意后者是i而不是get(key)得到value,因为如果key是重复的,后value会替换前value result = new int[]{map.get(target - nums[i]), i}; } // 把元素值及对应下标存入数组 map.put(nums[i],i); } return result; }