输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
首先做一个证明:
作者:马客(Mark)
链接:https://www.nowcoder.com/questionTerminal/390da4f7a00f44bea7c2f3d19491311b
来源:牛客网
找到的第一组(相差最大的),也就是乘积最小的。可以这样证明:考虑x+y=C(C是常数),xy的大小。不妨设y>=x,y-x=d>=0,即y=x+d, 2x+d=C, x=(C-d)/2, xy=x(x+d)=(C-d)(C+d)/4=(C2-d2)/4,也就是xy是一个关于变量d的二次函数,对称轴是y轴,开口向下。d是>=0的,d越大, xy也就越小。
因此设置头,尾两个迭代器,当找到第一组满足 两个数相加等于S的时候,这两个数也是乘积最小的。
如果两个数的和大于S,那么尾迭代器向头移动,直到等于或小于为止;
同理,如果两个数的和小于S,那么头迭代器向尾移动,直到等于或大于为止;
vector<int> FindNumbersWithSum(vector<int> array,int sum)
{
int i = 0, j = array.size() - 1;
vector<int> res;
while(i < j)
{
if(array[i] + array[j] == sum)
{
res.push_back(array[i]);
res.push_back(array[j]);
break;
}
while(i<j && array[i] + array[j] > sum)
{
j--;
}
while(i<j && array[i] + array[j] < sum)
{
i++;
}
}
return res;
}