1. 程式人生 > >Leetcode ---- 15.三數之和

Leetcode ---- 15.三數之和

題目:

給定一個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?找出所有滿足條件且不重複的三元組。

注意:答案中不可以包含重複的三元組。

例如, 給定陣列 nums = [-1, 0, 1, 2, -1, -4],

滿足要求的三元組集合為:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

 

思路:

這道題第一反應就是三個for迴圈再去重。很顯然,這樣做效率太低,時間複雜度太高。

那麼,仔細看這道題,  a + b + c = 0 =>  b+ c = -a

我們可以採用雙指標的方法。將a作為第一個迴圈引數,雙指標分別指向的是 b、c。通過判斷 a 與 b、c 之間的大小來移動雙指標。當然,最重要的前提,我們需要將該陣列進行排序,這樣,我們才能正確的找到滿足要求的組合。

期間,遇到相同的元素,則跳過。

 

程式:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<vector<int>> res;
        vector<int> tmp;
        if (nums.size() < 3)
            return res;
        
        int i = 0,j,k,val;
        int len = nums.size();
        while (i < len-2){
            j = i + 1;
            k = nums.size() - 1;
            val = -nums.at(i);
            while (j < k){
                if (nums[j]+nums[k] == val){
                    tmp.emplace_back(nums.at(i));
                    tmp.emplace_back(nums.at(j));
                    tmp.emplace_back(nums.at(k));
                    res.emplace_back(tmp);
                    tmp.clear();
                    j++;
                    k--;             
                    while (nums[j] == nums[j-1] && j < k){
                        j++;
                    }
                    while (nums[k] == nums[k+1] && j < k){
                        k--;
                    }
                }
                else if (nums[j]+nums[k] < val){
                    j++;
                }
                else{
                    k--;
                }
            }
            i++;
            while (nums[i] == nums[i-1]){
                i++;
            }
        }
        return res;
    }
};