题目:
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
共三种解法:
第一种,先对数组进行排序,并且得到排序后各元素对应于排序前的index,排完序后遍历一次数组,到第i个元素时,是否存在另一个元素(用二分查找),使得两者之和是否为target。这种方法的时间复杂度为O(n*lgn)。
第二种,先对数组排序,并且得到排序后各元素对应于排序前的index,然后用O(n)的时间判断两个元素的位置,思路为将头尾元素求和,将求和结果和target对比,如果sum<target,那么需要使sum增大,所以增大begin,否则减小end。时间复杂度为O(n*lgn)。
第三种,不需要排序,借助 一个HashMap,用O(n)的时间遍历一次数组,在遍历到数组i的时候,将<target-numbers[i], i>存入hashMap,如果在j>i的元素中遇到hashmap中包含numbers[j],则<i, j>就是要找的结果。时间复杂度为O(n)。
代码:
import java.util.Arrays;
import java.util.HashMap;
/**
* Number类便于保存排序后对应排序前的Index
* @author JeremyCai
*
*/
class Number implements Comparable<Number>{
int index;
int value;
public Number(int value, int index){
this.index = index;
this.value = value;
}
@Override
public int compareTo(Number o) {
if(this.value < o.value)
return -1;
else if(this.value == o.value)
return 0;
else
return 1;
}
}
public class Solution {
/**
* 先对数组排序,并且得到排序后各元素对应于排序前的index,然后用O(n)的时间判断两个元素的位置,思路为将头尾元素求和,
* 将求和结果和target对比,如果sum<target,那么需要使sum增大,所以增大begin,否则减小end
* @param numbers
* @param target
* @return
*/
public int[] twoSum(int[] numbers, int target) {
int[] result = new int[2];
Number[] numbersWithIndex = new Number[numbers.length];
for(int i = 0; i < numbers.length; i++) {
numbersWithIndex[i] = new Number(numbers[i], i);
}
Arrays.sort(numbersWithIndex);
int begin = 0;
int end = numbers.length - 1;
int sum;
while(begin <= end){
sum = numbersWithIndex[begin].value + numbersWithIndex[end].value;
if(sum == target){
result[0] = getMin(numbersWithIndex[begin].index, numbersWithIndex[end].index) + 1;
result[1] = getMax(numbersWithIndex[begin].index, numbersWithIndex[end].index) + 1;
System.out.println("result:" + result[0] + " " + result[1]);
return result;
}
if(sum < target)
begin++;
else
end --;
}
return result;
}
private int getMin(int a, int b){
if(a > b)
return b;
else
return a;
}
private int getMax(int a, int b){
if(a > b)
return a;
else
return b;
}
/**
* 用一个HashMap,遍历一遍数组中所有元素,如果hashmap中没有当前元素,则将target-当前元素得到的目的元素加入到hashmap中,用map的键存元素值,用map的值存放元素的位置
* @param numbers
* @param target
* @return
*/
public int[] twoSum2(int[] numbers, int target) {
int[] result = new int[2];
HashMap<Integer, Integer> numberMap = new HashMap<Integer, Integer>();
for(int i = 0; i < numbers.length; i++){
if(!numberMap.containsKey(numbers[i])){
numberMap.put(target - numbers[i], i);
}
else if(numberMap.containsKey(numbers[i])){
result[0] = getMin(i, numberMap.get(numbers[i])) + 1;
result[1] = getMax(i, numberMap.get(numbers[i])) + 1;
System.out.println("result:" + result[0] + " " + result[1]);
return result;
}
}
return result;
}
public static void main(String[] args){
Solution s = new Solution();
int[] numbers = {3, 3, 5};
int target = 8;
s.twoSum2(numbers, target);
}
}