题目链接
题目描述
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
示例
输入:
{1,2,3,4,10,11,12,13} 14
输出:
{1,13}
解题思路
- 二分查找的思想
- 定义首尾的两个指针,一个指针指向元素较小的值,一个指针指向元素较大的值。
- 指向较小元素的指针从头向尾遍历,
- 指向较大元素的指针从尾向头遍历。
- 如果两个指针指向元素的和
sum == target
,判断乘积大小。用变量保存小的两个数字 - 如果
sum > target
,移动较大的元素,使 sum 变小一些; 如果
sum < target
,移动较小的元素,使 sum 变大一些。代码
/*
二分查找思想
*/
public ArrayList<Integer> FindNumbersWithSum(int [] nums,int target) {
// 必须放在第一行定义,因为判断数组为空,或者找不到合适的数字时,需要返回空的ArrayList
ArrayList<Integer> arrlist = new ArrayList<>();
// 判断传入数组为空
if(nums.length==0 || nums==null){
return arrlist;
}
// 定义首尾的两个指针
int start=0,end=nums.length-1;
// 定义用来存放最小乘积
int minMulti = Integer.MAX_VALUE;
// 定义两个变量用来存放最小的两个数
int a=-1,b=-1;
// 开始遍历
while(start < end){
int sum = nums[start] + nums[end];
if(sum == target){
int multi = nums[start] * nums[end];
if(multi < minMulti){
a = nums[start];
b = nums[end];
minMulti = multi;
}
// 两端同时收缩
start++;
end--;
}
// 右侧收缩
else if(sum > target){
end--;
}
// 左侧收缩
else if(sum < target){
start++;
}
}
// 数组中没有找到合适的数字,返回初始定义的空ArrayList
if(a==-1 || b==-1){
return arrlist;
}
arrlist.add(a);
arrlist.add(b);
return arrlist;
}