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