参考自:《剑指Offer——名企面试官精讲典型编程题》
题目:和为s的两个数字
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,输出两个数的乘积最小的
主要思路:由于数组递增,则可以选择从最小值和最大值开始寻找,左边指针指向最小值,右边指针指向最大值,若两个数的和小于s,则增大较小的值(即左边指针向中间移动);若两个数的和大于s,则减小较大的值(即右边指针向中间移动);若等于s,则找到,否则,左右指针最终在中间相遇,说明不存在所求的数。
注:找到的第一对和为s的数字,也是乘积最小的两个数(因为两个数相差越远乘积越小)
。
关键点:左右指针向中间移动,保证查找的终止条件
时间复杂度:O(n)
public class NumbersEqualSum {
public static void main(String[] args) {
int[] array = {1, 2, 4, 7, 11, 15};
int sum = 15;
List<Integer> result = findNumbersWithSum(array, sum);
// [4, 11]
System.out.println(result.toString());
}
private static List<Integer> findNumbersWithSum(int[] array, int sum) {
if (array == null || array.length == 0) {
return new ArrayList<>();
}
return findMinProduct(array, sum);
}
private static List<Integer> findMinProduct(int[] array, int sum) {
List<Integer> result = new ArrayList<>();
int begin = 0;
int end = array.length - 1;
while (begin < end) {
int currentSum = array[begin] + array[end];
//因为相差越远乘积越小,所以直接返回第一对数据
if (currentSum == sum) {
result.add(array[begin]);
result.add(array[end]);
break;
} else if (currentSum < sum) {
begin++;
} else {
end--;
}
}
return result;
}
}