1. 程式人生 > >leetcode---最接近的三數之和

leetcode---最接近的三數之和

我的思路:

將整個陣列分成兩段,前面負數,後面非負數,然後前後各取出來一個數a,b,然後如果a+b>0,那麼c就從前面取,否則從後面取。

複雜度為(n/2*n/2*lgn)=O(n^2*lgn).但是超時間了。

其他思路:

一種時間複雜度為O(n^2)的解法:假設陣列中有len個元素,首先我們將陣列中的元素按照從小到大的順序進行排序。其次,看最終取出的三個數中的第一個數,若陣列長度為n,那麼有n種取法。假設取的第一個數是A[i],那麼第二三兩個數從A[i+1]~A[len]中取出。找到“第一個數為A[i]固定,後兩個數在A[i]後面元素中取。並且三數之和離target最近的情況。”這時,我們用兩個指標j,k分別指向A[i+1]和A[len],如果此時三數之和A[i]+A[j]+A[k]<target,說明三數之和小了,我們將j後移一格;反之,若和大於target,則將k前移一格;直到j和k相遇為止。在這期間,保留與target最近的三數之和。一旦發現有“和等於target的情況”,立即輸出即可。
 

我的實現程式碼(超時間)

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        
        int d,l=nums.size(),a,b,c;
        vector<vector<int>> res;
        sort(nums.begin(),nums.end());
        if(l==0) return res;
        int sum0=0;
        for(int i=0;i<l;i++)
        {
            if(nums[i]>=0) 
            {
                d=i;
                break;
            }
        }
        vector<int> t,temp;
        if(d+2<l&&nums[d]==0&&nums[d+1]==0&&nums[d+2]==0)
        {
            t.push_back(0);
            t.push_back(0);
            t.push_back(0);    
            res.push_back(t); 
        }  
        
         for(int i=d-1;i>-1;i--)
            for(int j=l-1;j>d-1;j--)
       //for(int i=0;i<d;i++)
            //for(int j=d;j<l;j++)
            {
                t.clear();
                a=nums[i];
                b=nums[j];
                c=a+b;
                if(c>0)
                {
                    //for(int k=d-1;k>-1;k--)
                    //int pos=binary_search(nums.begin(), nums.begin()+d, 0-c);
                    //cout<<"a"<<a<<b<<pos<<endl;
                    vector<int>::iterator it;  
                    it= lower_bound(nums.begin(), nums.end()+d, 0-c);
                    if(it!=nums.end()&&(*it)+c==0&&(it-nums.begin())!=i)  
                    //if(pos>-1&&pos!=i)
                    //if(nums[k]+c==0&&k!=i)
                        {t.push_back(a);
                         t.push_back(b);
                         t.push_back(-c);
                         //break;
                        }
                }
                else
                 {
                    //int pos=binary_search(nums.begin()+d, nums.end(), 0-c);
                    vector<int>::iterator it;  
                    it= lower_bound(nums.begin()+d, nums.end(), 0-c);

                    //for(int k=l-1;k>d-1;k--)
                    //if(nums[k]+c==0&&k!=j)
                    if(it!=nums.end()&&(*it)+c==0&&(it-nums.begin())!=j)    
                     {
                         t.push_back(a);
                         t.push_back(b);
                         t.push_back(-c);
                         //break;
                     }
                }
                
                int k=0;
                if(!t.empty())
                {
                    
                    sort(t.begin(),t.end());
                    for(k=0;k<res.size();k++)
                    {
                       temp=res[k];
                       if(temp[0]==t[0]&&temp[1]==t[1]&&temp[2]==t[2]) 
                       break;    
                    }
                    if(k==res.size())
                    res.push_back(t);    
                }
            }
        return res;
        
    }
};

使用新方法,剛開始還沒有通過,修改如下

1,如果a的值大於0;就是退出;不能是大於等於0,否則可能無法排除0 0 0

2,如果在res中排除重複,就無法通過

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        
        int d,dd,l=nums.size(),a=9,b,c,j,k,i,s;
        vector<vector<int>> res;
        sort(nums.begin(),nums.end());
        if(l==0) return res;
        vector<int> t,temp;
        for(i=0;i<l;i++)
        {
            if(a==nums[i]) continue;
            a=nums[i];
            if(a>0) break;
            j=i+1;
            k=l-1;
            while(j<k)
            {
                b=nums[j];
                c=nums[k];
                d=a+b+c;
                if(d==0)
                {
                   t.clear();
                   t.push_back(a);
                   t.push_back(b);
                   t.push_back(c);
                   res.push_back(t); 
                   /*if(!t.empty())
                    {

                        sort(t.begin(),t.end());
                        for(s=0;s<res.size();s++)
                        {
                           temp=res[s];
                           if(temp[0]==t[0]&&temp[1]==t[1]&&temp[2]==t[2]) 
                           break;    
                        }
                        if(s==res.size())
                        res.push_back(t);    
                    }*/
                   j++; while(nums[j]==b&&j<k) j++; 
                   k--; while(nums[k]==c&&j<k) k--;
                }else if(d<0)
                {  j++;
                   while(nums[j]==b&&j<k) j++; 
                }else
                {  k--;
                   while(nums[k]==c&&j<k) k--;
                }
            }
        }  
        
        
        return res;
        
    }
};