Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution.
Example:
Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].
题解:
这道题是比较经典处理数组的,有以下两个思路。
思路1:
利用HashMap,把target-numbers[i]的值放入hashmap中,value存index。遍历数组时,检查hashmap中是否已经存能和自己加一起等于target的值存在,存在的话把index取出,连同自己的index也出去,加1(index要求从1开始)后存入结果数组中返回。如果不存在的话,把自己的值和index存入hashmap中继续遍历。由于只是一遍遍历数组,时间复杂度为O(n)。
代码如下:
1 public int[] twoSum(int[] numbers, int target) {
2 int [] res = new int[2];
3 if(numbers==null||numbers.length<2)
4 return res;
5 HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
6 for(int i = 0; i < numbers.length; i++){
7 if(!map.containsKey(target-numbers[i])){
8 map.put(numbers[i],i);
9 }else{
10 res[0]= map.get(target-numbers[i])+1;
11 res[1]= i+1;
12 break;
13 }
14 }
15 return res;
16 }
HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,其中 HashMap 是 Map 接口的常用实现类,HashSet 是 Set 接口的常用实现类。虽然 HashMap 和 HashSet 实现的接口规范不同,但它们底层的 Hash 存储机制完全一样,甚至 HashSet 本身就采用 HashMap 来实现的。
实际上,HashSet 和 HashMap 之间有很多相似之处,对于 HashSet 而言,系统采用 Hash 算法决定集合元素的存储位置,这样可以保证能快速存、取集合元素;对于 HashMap 而言,系统 key-value 当成一个整体进行处理,系统总是根据 Hash 算法来计算 key-value 的存储位置,这样可以保证能快速存、取 Map 的 key-value 对。
在介绍集合存储之前需要指出一点:虽然集合号称存储的是 Java 对象,但实际上并不会真正将 Java 对象放入 Set 集合中,只是在 Set 集合中保留这些对象的引用而言。也就是说:Java 集合实际上是多个引用变量所组成的集合,这些引用变量指向实际的 Java 对象。
就像引用类型的数组一样,当我们把 Java 对象放入数组之时,并不是真正的把 Java 对象放入数组中,只是把对象的引用放入数组中,每个数组元素都是一个引用变量。
思路2:
又碰到敏感的关键字array和target,自然而然想到二分查找法。但是这道题不能像传统二分查找法那样舍弃一半在另外一半查找,需要一点点挪low和high指针,所以时间复杂度为O(n)。
首先先将整个list拷贝并排序,使用Arrays.Sort()函数,时间复杂度O(nlogn)
然后利用二分查找法,判断target和numbers[low]+numbers[high]。
target == numbers[low]+numbers[high], 记录copy[low]和copy[high];
target > numbers[low]+numbers[high],说明最大的和最小的加一起还小于target,所以小值要取大一点,即low++;
target > numbers[low]+numbers[high], 说明最大的和最小的加一起大于target,那么大值需要往下取一点,即high--。
再把找到的两个合格值在原list中找到对应的index,返回即可。
总共的时间复杂度为O(n+nlogn+n+n) = O(nlogn)。
代码如下: 1 public int[] twoSum(int[] numbers, int target) {
2 int [] res = new int[2];
3 if(numbers==null||numbers.length<2)
4 return res;
5
6 //copy original list and sort
7 int[] copylist = new int[numbers.length];
8 System.arraycopy(numbers, 0, copylist, 0, numbers.length);
9 Arrays.sort(copylist);
10
11 int low = 0;
12 int high = copylist.length-1;
13
14 while(low<high){
15 if(copylist[low]+copylist[high]<target)
16 low++;
17 else if(copylist[low]+copylist[high]>target)
18 high--;
19 else{
20 res[0]=copylist[low];
21 res[1]=copylist[high];
22 break;
23 }
24 }
25
26 //find index from original list
27 int index1 = -1, index2 = -1;
28 for(int i = 0; i < numbers.length; i++){
29 if(numbers[i] == res[0]&&index1==-1)
30 index1 = i+1;
31 else if(numbers[i] == res[1]&&index2==-1)
32 index2 = i+1;
33 }
34 res[0] = index1;
35 res[1] = index2;
36 Arrays.sort(res);
37 return res;
38 }