LeetCode 15. 3Sum

LeetCode 15. 3Sum

題目要求:給出一個整型數組S。找出裏面所有的a,b,c使得a+b+c=0,要求每組數據不能完全相同。
題目給出的框架如下:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {

    }
};

解題思路

3Sum與2Sum的思路是一致的,都是先進行排序,然後採用首尾兩個標記,然後向中間移動。


2Sum的情況

如果我們處理的是2Sum的話,對其進行排序後,用下標i指向0,下標j指向尾部,i和j的移動情況有以下三種:

  1. 如果nums[i]+nums[j]==0,則i和j必須同時向中間移動,只移動一個的話,相加得到的結果必然是要麼大於要麼小於;
  2. 如果nums[i]+nums[j]<0,那麼就只能增大nums[i]+nums[j]的值,只有i向右移動,nums[i]的值增大,兩者的和纔會增大;
  3. 同理,如果nums[i]+nums[j]>0,那麼只有j向中間移動,兩者之後纔有可能等於0。
  4. 最後需要注意的是,因爲要求每組結果不能完全相同,因此,在移動的過程中,如果元素相同,則需要跳過。

3Sum的情況

3Sum與2Sum的情況類似,具體做法如下:

  1. 固定一個數k,在它後面找出兩個數i=k+1j=length-1,i和j不斷向中間移動,使得nums[i]+nums[j]=0-nums[k]
  2. k從0開始移動至length-3的位置(至少需要留兩個位置給i和j),這樣就能找出所有的元素使得nums[i]+nums[j]+nums[k]=0;
  3. 同時,爲了排除相同的結果,i,j,k移動的時候碰到相同的元素應當跳過;
  4. 此外,當nums[k]>0的時候可以提前結束搜索,因爲不可能存在3個大於0的數之和爲0。

代碼實現

代碼實現如下:

class Solution {
public:
    vector<vector<int> > threeSum(vector<int> &num) {
        vector<vector<int> > v;

        if (num.size() == 0)
            return v;

        sort(num.begin(), num.end());

        for (int k = 0; k < num.size() - 2 && num[k] <= 0; ++k) {
            if (k > 0 && num[k] == num[k - 1]) // 跳過重複元素
                continue;

            int i = k + 1, j = num.size() - 1;
            while (i < j) {
                if (num[i] + num[j] == 0 - num[k]) {
                    vector<int> temp;
                    temp.push_back(num[k]);
                    temp.push_back(num[i]);
                    temp.push_back(num[j]);
                    v.push_back(temp);

                    while (++i < j && num[i] == num[i - 1])
                        ; // 跳過重複元素
                    while (i < --j && num[j] == num[j + 1])
                        ; // 跳過重複元素
                } else if (num[i] + num[j] > 0 - num[k])
                    --j;
                else
                    ++i;
            }
        }

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