刷題 - 和爲S的兩個數 - 雙指針

題目描述:

輸入一個遞增排序的數組和一個數字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;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章