题目
题号:42
题目名:和为S的两个数字
编程语言
Java
题目描述
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
输出描述:
对应每个测试案例,输出两个数,小的先输出。
初次思路
题目要求意思就是求出a+b=sum的a和b的所有集合中乘积最小的一对数
1.由于数组是递增数组,那么可以用双端指针,一个指向头,一个指向尾,固定前端,由后端向前遍历
2.如果头+尾对应的数和为sum,那说明找到了,用他们的乘积和保存的最小乘积相比,如果比最小乘积要小,那就保留这两个数到res,然后前指针后移,后指针前移往中间走
3.如果a+b<sum了,那可以直接移动前指针向前就行了
4.如果a+b>sum,说明还后端需要继续找更小的数使得a+b=sum
5.最后返回res
解题代码
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int [] array, int sum) {
ArrayList<Integer> res = new ArrayList<>();
if(array==null || array.length ==0||array[array.length-1]*2<=sum||array[0]*2>=sum) return res;
/**1,3,7,8,10,13,17 16
* a+b=sum.如果sum不变,a增加,b需要减少
* 定义两个指针,头尾指针
* 左边定住,右边移动,如果找到a+b=sum,则加入res,头指针后移,尾指针前移;
* 如果a+b<sum了,说明移动尾指针找不到了,直接开始下一次循环;
* 比如1,2,3,4,5,6
*/
int last =array.length-1;
int min = Integer.MAX_VALUE;
int ret1 = 0;
int ret2 = 0;
for (int first = 0; first < array.length; first++) {
if(first>=last) break;
while (first<last) {
ret1 = array[first];
ret2 = array[last];
if(ret1+ret2==sum&&ret1*ret2<min) {
res.add(array[first]);
res.add(array[last]);
min = ret1 * ret2;
last--;
}else if(ret1+ret2<sum){
break;
}else {
last--;
}
}
}
return res;
}
}
算法练习代码我都开源在码云上,有需要的朋友可以看看