输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
输出描述: 对应每个测试案例,输出两个数,小的先输出。
代码
解法一
暴力法,遍历所有,依次和之后的所有数字求和判断是否为S
public static List<List<Integer>> findContinuesSequence(int[] array, int s) { // 和为s的两个数,所以数组长度最小也得是2 if (array == null || array.length < 2) { return null; } // 保存结果 List<List<Integer>> result = Lists.newArrayList(); for (int i = 0; i < array.length - 1; i++) { for (int j = i + 1; j < array.length; j++) { if (array[i] + array[j] == s) { result.add(Lists.newArrayList(array[i], array[j])); } } } return result; }
解法二
参照上篇和为S的连续正数序列中的方法,定义两个指针,已知数组是有序递增的
- 当和大于S时,移动end指针向前,相当于减去两个数字之间的差值
- 当和小于S时,移动start指针向后,相当于加上两个数字之间的差值
- 当和等于S时,可以移动end指针向前,也可以移动start指针向后,目的都是找寻下一组数字
public static List<List<Integer>> findContinuesSequence(int[] array, int s) { // 和为s的两个数,所以数组长度最小也得是2 if (array == null || array.length < 2) { return null; } // 初始化两个指针,一个指向数组的开始位置,一个指向数组的结束位置 int start = 0; int end = array.length - 1; // 保存结果 List<List<Integer>> result = Lists.newArrayList(); while (start < end) { int sum = array[start] + array[end]; // 如果两个数字的和等于目标值,则记录,同时将end向前移动(将start向后移动也可以,本质都是为了下一次搜索) // 如果和小于目标值,向后移动start,因为end是向前移动的,而数组是递增的,向前移动只会更小 // 如果和大于目标值,向前移动end,因为递增,所以该操作等于减去两个元素之间的差值 if (sum == s) { result.add(Lists.newArrayList(array[start], array[end])); //start++; end--; } else if (sum < s){ start++; } else { end--; } } return result; }