题目:
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, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
解法一:
思路:
这道题采用了双指针,即头部和尾部各有一个指针,从头部、尾部分别向中间查找,直到满足和为target为止。
步骤:
1. 把原数组复制一遍,接着调用Java的Arrays.Sort()函数对数组进行从小到大排序。
2. 进行二分查找法,判断target和copy[low]+copy[high]。
- target == copy[low]+copy[high], 记录copy[low]和copy[high];
- target < copy[low]+copy[high]或target > copy[low]+copy[high],移动前端或后端的指针。
3.把找到的两个合格值在原list中找到对应的index,返回即可。
注:
1. 程序的边界条件:如果一组数字为空或者这组数字为<=2个,直接返回这组数即可。
2. Arrays.sort()排序是采用快速排序并且是从小到大的排序方法。
3. System的静态方法arraycopy()可以实现数组的复制。函数原型是:public static void arraycopy(Object src, int srcPos,Object dest, int destPos, int length);src为源数组; srcPos:源数组要复制的起始位置;dest:目的数组;destPos:目的数组放置的起始位置;length:复制的长度。其中目的数组和源数组必须是同类型或者类型可以转换的数组。
public class Solution{
public int[] twoSum(int[] numbers, int target)
{
//生成长度为2的数组,用于输出最后结果
int[] res = new int[2];
//边界条件:如果输入的一组数字为空或者小于2个,直接返回这组数
if(numbers==null||numbers.length<2)
return res;
//复制原数组并按照从小到大排序
int[] copylist = new int[numbers.length];
System.arraycopy(numbers,0,copylist,0,numbers.length);
Arrays.sort(copylist);
int low = 0;
int high = copylist.length-1;
//双指针头尾查找
while(low<high)
{
if(copylist[low]+copylist[high]<target)
low++;
else if(copylist[low]+copylist[high]>target)
high--;
else
{
res[0]=copylist[low];
res[1]=copylist[high];
break;
}
}
//对照原数组找出两个数值的index并返回
int index1 = -1,index2 = -1;
for(int i = 0;i<numbers.length;i++){
if(numbers[i] == res[0]&&index1 == -1)
index1 = i;
else if(numbers[i] == res[1]&&index2 == -1)
index2 = i;
}
res[0] = index1;
res[1] = index2;
Arrays.sort(res);
return res;
}
}
解法二:利用hashmap
可以使用哈希表优化,让寻找差值是否在nums中这个操作的时间复杂度从O(N)下降到O(1),整体时间复杂度变为O(N),性能得到极大提升。
精彩在hashmap中以数的值为key,index为value,每次检测是否有target-值得key,时间o(n)
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] res = new int[2];
if(nums==null||nums.length <2)
return res;
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i=0; i<nums.length ;i++){
if(map.containsKey(target-nums[i])){
res[0]=i;
res[1]=map.get(target-nums[i]);
}
else
map.put(nums[i],i);
}
Arrays.sort(res);
return res;
}
}