双指针。本题的关键是数组是递增排序的。那么我们可以定义两个指针,初始化第一个指针指向数组中第一个(最小的)数字,第二个指针指向数组的最后一个(最大的)数字。
时间复杂度:只有一个while循环,由于是从两端向中间扫描数组,因此复杂度是O(n)。要优于固定一个数字再对后面数字遍历的方法(这种方法O(n^2))。
import java.util.ArrayList; public class Solution { // Note:题目要求输出两个数乘积最小的一对 //不要被题目误导了!乘积最小的那一对就是最先找到的,直接返回即可。 //例如,1,2,3,4,5,6 要求sum为7,那么最外层的1和6的乘积要 小于 内层(2*5、3*4) //用数学分析一波,a + b = sum,那么较小的数字a和较大的数字b满足大小关系: a < sum/2 < b 即a在对称轴左侧 // 设x是较小的那个数,乘积x(7-x)= -x^2+7x,在对称轴左侧是单调递增的,说明x越小乘积越小。 public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) { ArrayList<Integer> res = new ArrayList<>(); if (array == null || array.length == 0) return res; int smallIndex = 0; // 这里small和big记录的都是下标 int bigIndex = array.length - 1; while (smallIndex < bigIndex){ int tempSum = array[smallIndex] + array[bigIndex]; if (tempSum == sum){ res.add(array[smallIndex]); res.add(array[bigIndex]); // 最外层的乘积最小 break; }else if (tempSum < sum){ smallIndex++; }else{//tempSum > sum bigIndex--; } } return res; } }
原文:https://www.cnblogs.com/HuangYJ/p/13562070.html