坑死人不偿命的3Sum,知道思路,改了一晚上才改好,各种小错
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
/** 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)
*
* \param
* \param
* \return
* 核心问题是如何去重,一种方法是用set(超时),
* 另一种是,利用排序后的数进行去重判断是否和前一个数相等,若相等 continue
*/
class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
vector<vector<int> > result;
vector<int> re;
int n=num.size();
if(n<3)
return result;
sort(num.begin(),num.end());//sort the vector num
for(int i=0;i<n;i++){
int last=n-1;
int j=i+1;
if(i!=0&&num[i]==num[i-1])
continue;
while(j<last){
re.clear();//用clear来清空上次数据
int sum=num[i]+num[j]+num[last];
if(sum<0)
j++;
else if(sum>0)
last--;
else{
re.push_back(num[i]);// store in the result!!!
re.push_back(num[j]);
re.push_back(num[last]);
// cout<<"size 1"<<re.size()<<endl;
j++;
last--;
result.push_back(re); //no rows ,so cannot use result[i].push_back or result[i]=re;
while(j!=(i+1)&&num[j]==num[j-1])
j++;
while(last!=n-1&&num[last]==num[last+1])
last--;
}
}
}
//sort(result.begin(),result.end());
return result;
}
};
int main()
{
Solution s;
vector<vector<int> > result;
vector<int> num;
num.push_back(1);
num.push_back(0);
num.push_back(-1);
// num.push_back(2);
num.push_back(-1);
//num.push_back(-4);
num.push_back(0);
result=s.threeSum(num);
for(int i=0;i<result.size();++i){
for(int j=0;j<result[i].size();++j)
cout<<result[i][j]<<" ";
cout<<endl;
}
return 0;
}
错误
1.output limit exceed 输出重复行报错
2.超时,因为多个if-elseif-elseif造成超时。
后来发现把第二,三个元素去重的判断写成while循环放在sum里最高效,这样直接对可能的结果操作而不是所有数每个都判断,可是减少时间
3.智障错误,把第一个元素的去重判断写成了,后来才发现j=i+1,而不是i-1
if(i!=0&&num[i]==num[j])