题目描述:
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,
如果有多对数字的和等于S,输出两个数的乘积最小的。
输出描述:对应每个测试案例,输出两个数,小的先输出。
思路:
思路1:O(n),好
既然是排序好的,就好办了:左右加逼,注意本题和上题对比:都是双指针,本题是夹逼,上题是窗口右移
假设:若b>a,且存在,
a + b = s;
(a - m ) + (b + m) = s
则:(a - m )(b + m)=ab - (b-a)m - m*m < ab;说明外层的乘积更小,
也就是说依然是左右夹逼法,不断往中间靠!!!只需要2个指针
1.left开头,right指向结尾
2.如果和小于sum,说明太小了,left右移寻找更大的数
3.如果和大于sum,说明太大了,right左移寻找更小的数
4.和相等,把left和right的数返回
思路2:我的,O(n^2),不太好
1.从第一个开始遍历,往后找,因为有序,后面一个肯定要>=
2.记录乘积multi,遍历结束multi最小的即为所求
*/
public class Solution {
public static void main(String[] args) {
int[] array = {1, 2, 4, 7, 11, 15};
Solution s = new Solution();
ArrayList<Integer> res = s.FindNumbersWithSum(array, 15);
}
public ArrayList<Integer> FindNumbersWithSum(int[] array, int sum) {
ArrayList<Integer> resList = new ArrayList<>();
if (array == null || array.length < 2) {
return resList;
}
int plow = 0;
int phight = array.length - 1;
while (plow < phight) {
if (array[plow] + array[phight] == sum) {
resList.add(array[plow]);
resList.add(array[phight]);
break;
} else if (array[plow] + array[phight] > sum) {
phight--;
} else {
plow++;
}
}
return resList;
}
public ArrayList<Integer> FindNumbersWithSum2(int[] array, int sum) {
ArrayList<Integer> resList = new ArrayList<>();
/*if (array == null || array.length < 2) {//注意小于2不是=0
return resList;
}*/
int[] resArr = new int[2];
int tmp;
int multi = Integer.MAX_VALUE;
boolean flag=false;
for (int i = 0; i < array.length; i++) {
tmp = array[i];
for (int j = i + 1; j < array.length; j++) {
if (array[j] + tmp == sum && tmp * array[j] < multi) {
multi = tmp * array[j];
resArr[0] = tmp;
resArr[1] = array[j];
flag=true;
break;
}
}
}
if (flag) {
resList.add(resArr[0]);
resList.add(resArr[1]);
}
return resList;
}
}