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;
}
};