【题目】
输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
【基本思路】
使用两个指针small和big,small表示第一个数字的位置,big表示第二个数字的位置。初始时,small = 0,big = 数组最后一个位置。如果arr[small] + arr[big] < S,small++;如果arr[small] + arr[big] > S,big–;如果arr[small] + arr[big] = S,直接输出。
当遇到第一组和为S的数就直接输出,这是因为第一组一定就是乘积最小的。证明如下:
设两数为
x,y(y>x)
,且
x+y=C,y−x=d
则有
y=x+d,2x+d=C
所以
x=C−d2
因此
x∗y=C−d2∗(C−d2+d)=−d24+C24
x∗y
是一个关于d的对称轴为y的开口向下的二次函数,d越大,乘积越小。
【代码实现】
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
vector<int> res;
if(array.size() == 0){
return res;
}
int small = 0;
int big = array.size() - 1;
while(small < big){
if(array[small] + array[big] < sum){
small++;
}
else if(array[small] + array[big] > sum){
big--;
}
else{
res.push_back(array[small]);
res.push_back(array[big]);
break;
}
}
return res;
}
};