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迴圈加上二分查詢,發現寫出來跑的賊慢。。。

但是終歸是自己寫的。。。還是要貼一下的。。。。

寫的賊麻煩,又臭又長。。。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ve;
        if(nums.size()<3)
            return ve;
        sort (nums.begin(),nums.end(),less<int>());
        int Size=nums.size();
        int temp1=0x3f3f3f3f,temp2=temp1;
        for (int i=0;i<Size-2;i++)
        {
            while (nums[i]==temp1)
            {
                i++;
            }
            if(i>=Size-2)
                break;
            temp1=nums[i];
            for (int j=i+1;j<Size;j++)
            {
                while (nums[j]==temp2)
                {
                      j++;
                }
                if(j>=Size-1)
                     break;
                temp2=nums[j];
                if(j<Size-1&&binarySearch(-(nums[i]+nums[j]),nums,j+1,Size-1)!=-1)
                    ve.push_back({nums[i],nums[j],-(nums[i]+nums[j])});
            }
        }
        return ve;
    }
    int binarySearch (int x,vector<int>& nums,int left,int right)
    {
        while (left<=right)
        {
            int mid=(left+right)>>1;
            if(nums[mid]==x)
                return mid;
            else if(nums[mid]>x)
                right=mid-1;
            else 
                left=mid+1;
        }
        return -1;
    }
};

 看標準程式的程式碼。。原來還有更簡單的辦法。。。標準程式是遍歷一遍序列,先找出第一個元素a,然後將b和c分別設為當前遍歷的位置+1和序列最後一個元素。。然後與0比較,如果小了則b往前移,如果大了,c往後移。。。直到找到為0的點。。。

一定要注意有重複元素的情況。。。

程式碼如下:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ve;
        if(nums.size()<3)
            return ve;
        sort (nums.begin(),nums.end(),less<int>());
        int Size=nums.size();
        for (int i=0;i<Size-2;i++)
        {
            if(i==0||i>0&&nums[i]!=nums[i-1])
            {
                int l=i+1,r=Size-1;
                while(l<r)
                {
                    int sum=nums[i]+nums[l]+nums[r];
                    if(sum==0)
                    {
                        ve.push_back({nums[i],nums[l],nums[r]});
                        l++;
                        while (nums[l-1]==nums[l]&&l<Size-1)
                              l++;
                    }
                    else if(sum>0)
                        r--;
                    else 
                        l++;
                }
            }
        }
        return ve;
    }
};