题目描述:
输入一个递增排序的数组array和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,返回任意一组即可,如果无法找出这样的数字,返回一个空数组即可。
数据范围:
0<=len(array)<=105
1<=array[i]<=106
示例1:
输入:[1,2,4,7,11,15],15
返回值:[4,11]
说明:返回[4,11]或者[11,4]都是可以的
示例2:
输入:[1,5,11],10
返回值:[]
说明:不存在,返回空数组
示例3:
输入:[1,2,3,4],5
返回值:[1,4]
说明:返回[1,4],[4,1],[2,3],[3,2]都是可以的
解法一:双指针逼近法
思路:由题目可知:该数组是有序递增数组,因此可以利用两个指针 left 和 right,left 指向数组首元素的下标,right 指向数组末元素的下标。遍历数组,判断当前 array[left] 和 array[right] 的和。如果 array[left] 和 array[right] 的和大于 sum ,则 right--。
如果 array[left] 和 array[right] 的和小于 sum ,则 left ++;
如果 array[left] 和 array[right] 的和等于 sum ,则 找到结果,退出循环。
以示例1为例,如下图:
代码如下:
import java.util.*;
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
//存储结果
ArrayList<Integer> list = new ArrayList<>();
//双指针
int left = 0, right = array.length-1;
while(left < right){
//如果array[left]和array[right]的和小于sum,则left++
if(array[left] + array[right] < sum){
left ++;
}else if(array[left] + array[right] > sum){//如果array[left]和array[right]的和大于sum,则right--
right --;
}else{ //如果array[left]和array[right]的和等于sum,找到结果,直接跳出循环
list.add(array[left]);
list.add(array[right]);
break;
}
}
return list;
}
}
解法二:HashMap。
思路:利用HashMap存放元素和下标,然后开始遍历数组找到和为sum的两个元素,从左到右找到的第一对和为sum的就是最小的一对。
以示例一为例:
代码如下:
import java.util.*;
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
ArrayList<Integer> list = new ArrayList<>();
Map<Integer, Integer> map = new HashMap<>();
//将数组中的元素存入map,key为array[i],value为当前元素的下标
for(int i=0; i < array.length; i++){
map.put(array[i], i);
}
//遍历数组
for(int i=0; i < array.length; i++){
//得到sum-array[i]的值,判断val是否存在于map中
int val = sum - array[i];
//如果存在,则找到和为sum的值
if(map.containsKey(val)){
list.add(array[i]);
list.add(val);
break;
}
}
//返回结果
return list;
}
}