您的位置:首页 > 其它

leetcode 题解 || 3Sum 问题

2015-03-18 19:11 399 查看
problem:

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0?
Find all unique triplets in the array which gives the sum of zero.

Note:
Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
The solution set must not contain duplicate triplets.
For example, given array S = {-1 0 1 2 -1 -4},

A solution set is:
(-1, 0, 1)
(-1, -1, 2)

找到三个和为0的数,按顺序输出,并且去掉重复的组合

thinking:

(1)直觉告诉我,先排序再搜索要更简单。

(2)双数求和可以采用二分查找(双指针),时间复杂度可以控制在O(nlogn),也可以推广到三数求和上!!!

但具体实现的时候,我走了弯路,导致时间复杂度最坏达到0(n*n)

先看看优秀的实现,确实很精细和简洁,细细品味:

class Solution {
public:

//插入排序
void InsertSort(vector<int> &a, int n)
{
int temp;
for (int i = 1; i < n; ++i)
{
temp = a[i];
int j;
for (j = i; j > 0 && temp < a[j - 1]; --j)
{
a[j] = a[j - 1];
}
a[j] = temp;
}
}

vector<vector<int> > threeSum(vector<int> &num) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.

vector<vector<int>> res;

if (num.size() < 3) //小于3个数
return res;

//对原数组非递减(递增)排序
InsertSort(num,num.size());

for (int i = 0; i < num.size(); ++i)
{
//去重
if (i != 0 && num[i] == num[i-1])
continue;

int p = i + 1, q = num.size() - 1;
int sum = 0;

//收缩法寻找第2,第3个数
while (p < q)
{
sum = num[i] + num[p] + num[q];

if (sum == 0)
{
vector<int> newRes;
newRes.push_back(num[i]);
newRes.push_back(num[p]);
newRes.push_back(num[q]);
InsertSort(newRes,newRes.size());
res.push_back(newRes);

//寻找其他可能的2个数,顺带去重
while (++p < q && num[p-1] == num[p])
{
//do nothing
}
while (--q > p && num[q+1] == num[q])
{
//do noghing
}
}
else if (sum < 0) //和太小,p向后移动
{
++p;
}
else //和过大,q向前移动
{
--q;
}
}
}

return res;
}
};最后贴上我自己的版本,结果本地实测通过。
void find(int i, int &p, int j,vector<int> tmp, vector<vector<int> > &result)
{
cout<<"i "<<i<<"p "<<p<<"j"<<j<<endl;
cout<<tmp.at(i)<<"_"<<tmp.at(p)<<"_"<<tmp.at(j)<<endl;
int index=0xff;
while((index!=0x00)&&(p!=i)&&(p!=j))
{
if(tmp.at(i)+tmp.at(p)+tmp.at(j)>0)
{
p--;
index&=0x0f;
}
else if(tmp.at(i)+tmp.at(p)+tmp.at(j)<0)
{
p++;
index&=0xf0;
}
else if(tmp.at(i)+tmp.at(p)+tmp.at(j)==0)
{
vector<int> a;
a.push_back(tmp.at(i));
a.push_back(tmp.at(p));
a.push_back(tmp.at(j));
result.push_back(a);
cout<<"a.size() "<<a.size()<<endl;
return;
}

}//while
}

class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
vector<vector<int> > result;
vector<vector<int> > result_1;
int i=0;
int j=num.size()-1;
int index1=0;
vector<int> tmp(num);
sort(tmp.begin(),tmp.end());
while((j-i>1)&&(index1<tmp.size()))
{
int p=(i+j)/2;
find(i,p,j,tmp,result);
if(tmp.at(i)+tmp.at(p)+tmp.at(j)<0)
{
i++;
index1++;
}
else
{
index1++;
j--;
}
}//while
unique_copy(result.begin(),result.end(),back_inserter(result_1));
return result_1;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息