題目描述:
輸入一個遞增排序的數組和一個數字S,在數組中查找兩個數,使得他們的和正好是S,如果有多對數字的和等於S,輸出兩個數的乘積最小的。
解題思路:
筆者在前面刷題系列中寫了一個 “ 和爲S的連續正數序列 ”,這個問題中採用了雙指針的方法,本題中同樣可以採用這種方法。
對給定的遞增序列,給定兩個雙指針分別指向數列頭和尾,將指針指向的兩個數據求和,與S比較:
(1)s1+s2 = S,找到了一組滿足條件的數據,返回結果即可;
(2)s1+s2 > S,需要縮小,則s2後移一位繼續判斷;
(3)s1+s2 < S,需要增大,則s1前移一位繼續判斷;
爲什麼按此方法找到的第一組數據就是乘積最小的一組?
假定:s1+s2 = S,s2-s1 = d;則2s1+d = S =》 s1 = (S-d)/2 =》s1*s2 = s1*(s1+d) = (S-d)(S+d)/4 = (S^2 - d^2)/4。
由此可知,在S一定時,d越大,乘積越小,即兩個數s1和s2之間的距離越大,乘積越小。
class Solution {
public:
vector<int> FindNumbersWithSum(const vector<int>& a,int sum) {
vector<int> res;
int n = a.size();
int low = 0, high = n - 1;
while(low < high){
if(a[low] + a[high] == sum){
res.push_back(a[low]);
res.push_back(a[high]);
break;
}
while(low < high && a[low] + a[high] > sum)
--high;
while(low < high && a[low] + a[high] < sum)
++low;
}
return res;
}
};