Q:输入一个递增序列的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和为S,输出两个数的乘积最小的
解题思路:
- 查找两个数和为S,没有要求数字连续,因此我们可以采用“首尾指针法”
- 第一个指针指向数组第一个元素,另一个指针指向数组最后一个元素,当它们的和大于S时证明和大了,因此要将尾指针左移减小和的大小;当和小于S时证明和小了,因此要将首指针右移增大和;
- 最后要考虑的是乘积最小的情况,通常做法是依次比较乘积记录最小值,但这里有个简便方法是:在和相等的情况下,如果首尾距离越远则乘积越小;因此我们找到的第一队首尾和为S的乘积和是最小的,下面给出公式证明:
代码:
1.简便方法
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
int i=0;
int j=array.size()-1;
vector<int> res;
while(i<j)
{
int tmp=array[i]+array[j];
if(tmp==sum)
{
res.push_back(array[i]);
res.push_back(array[j]);
return res;
}
else if(tmp<sum)
++i;
else
--j;
}
return res;
}
};
2.比较法
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
vector<int> res;
int i=0;
int j=array.size()-1;
int tmp=INT_MAX;
while(i<j)
{
int count=array[i]+array[j];
int mul=array[i]*array[j];
if(count==sum)
{
if(mul<tmp)
{
res.clear();
res.push_back(array[i]);
res.push_back(array[j]);
tmp=mul;
}
++i;
--j;
}
else if(count<sum)
++i;
else
--j;
}
return res;
}
};