Given an array of integers, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
1. 索引1必须小于索引2,是key而非value //where index1 must be less than index2
2. 只有唯一解 //You may assume that each input would have exactly one solution.
1. 一开始,我的想法是先对数组进行排序,然后再对排序数组通过循环进行配对,这样的时间复杂度是O(n+n2)
public class Solution { public int[] twoSum(int[] nums, int target) { int tmp; boolean flag = false; int numbers[] = new int[2]; for(int i = 0; i < nums.length-1; i++){ tmp = nums[i]; if (nums[i] >= nums[i+1]){ nums[i] = nums[i+1]; nums[i+1] = tmp; } } for(int i =0; i < nums.length && !flag; i++){ for(int j =0; j < nums.length; j++){ if (i == j) continue; else { if(nums[i] + nums[j] == target) { numbers[0] = i+1; numbers[1] = j+1; flag = true; break; } } } } return numbers; } }
2. 然而,这样做的问题会导致最终输出的Index是排序数组的Index,而如果对原数组的每个下标进行标记,显然时间复杂度大大超出了可承受的范围
3. 其实通过Hashmap的containsKey方法可以极简介地解决这个问题
public class Solution { //解题思路是通过寻找HashMap中target减去一个加数所得的结果来寻去另一个加数 //举例来说,数组[3,2,4], target = 6 //第一次运行,Map没有内容,不满足判断,将3添加到HashMap //第二次运行,target - num[1] = 4, 不满足判断,将2天假到HashMap //第三次运行,target - num[2] = 2, 满足判断, 返回[map中的加数,当前加数] //index1 must be less than index2 //将妙之处在于1. 通过target - nums[i]这个条件,完成了对sum组成数的寻去和index1 must be less than index2的条件 // 2. 使用上通过containsKey,等于把key当成value来用 // 3. Java可以通过return new int[]{...}来直接返回数组,这也体现了Java中一切都是对象的原则 public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for(int i = 0; i < nums.length; i++) { if(map.containsKey(target - nums[i])) return new int[]{map.get(target - nums[i]), i+1}; map.put(nums[i], i+1); } return new int[]{0,0}; } }