题目描述:
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
输出描述:
对应每个测试案例,输出两个数,小的先输出。
思路分析:
假设a<b,则ab>(a-1)(b+1)。这说明,从左侧开始先找到的数肯定是乘积最小的数。所以开始的思路就是从左侧开始遍历,直到找出满足条件的两个数放入集合中。但是这样的话,递增排序的数组的这一个条件就基本上没用上,而且时间复杂度是大于O(N)的。所以根据题意以及分析可知,可以采用头尾双指针的方法,若两数的和大于sum,则将右指针左移一位再进行判断,若两数的和小于sum,则将左指针右移一位再进行判断,边界条件是左指针小于右指针。
方法1:暴力遍历法
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int[] array,int sum) {
int p1 = 0;
int p2 = 1;
ArrayList<Integer> list = new ArrayList<>();
if(array == null || array.length < 2){
return list;
}
while(array[p1] + array[p2] <= sum ){
for(int i = p1,j = p2; j < array.length; j++){
if(array[i]+array[j]==sum){
list.add(array[i]);
list.add(array[j]);
return list;
}
if(array[i]+array[j] > sum){
break;
}
}
p1++;
p2 = p1+1;
}
return list;
}
}
方法2:头尾双指针的方法
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int[] array,int sum) {
ArrayList<Integer> list = new ArrayList<>();
if(array == null || array.length < 2){
return list;
}
int i = 0;
int j = array.length-1;
while(i < j){
if(array[i]+array[j]==sum){
list.add(array[i]);
list.add(array[j]);
return list;
}
else if(array[i]+array[j] > sum){
j--;
}
else{
i++;
}
}
return list;
}
}