leetcode---最接近的三数之和[1]

https://leetcode-cn.com/problems/3sum/description/

我的思路:

将整个数组分成两段,前面负数,后面非负数,然后前后各取出来一个数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;
        
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值