您的位置:首页 > 其它

LeetCode 遍历技巧 | 15. 3Sum

2017-03-02 12:55 351 查看
/*
* Leetcode15. 3Sum
* Funtion: 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.
* Example:
Input: given array S = [-1, 0, 1, 2, -1, -4],
Output: [
[-1, 0, 1],
[-1, -1, 2]
]
注意:当输入为[0,0,0]时,输出为[[0,0,0]]
Input:[1,1,-2]Expected:[[-2,1,1]]
Input:[3,0,-2,-1,1,2]Expected:[[-2,-1,3],[-2,0,2],[-1,0,1]]
Input:[-4,-2,1,-5,-4,-4,4,-2,0,4,0,-2,3,1,-5,0]Expected:[[-5,1,4],[-4,0,4],[-4,1,3],[-2,-2,4],[-2,1,1],[0,0,0]]
Input:113个数[8,5,12,3,-2,-13,-8,-9,-8,10,-10,-10,-14,-5,-1,-8,-7,-12,4,4,10,-8,0,-3,4,11,-9,-2,-7,-2,3,-14,-12,1,-4,-6,3,3,0,2,-9,-2,7,-8,0,14,-1,8,-13,10,-11,4,-13,-4,-14,-1,-8,-7,12,-8,6,0,-15,2,8,-4,11,-4,-15,-12,5,-9,1,-2,-10,-14,-11,4,1,13,-1,-3,3,-7,9,-4,7,8,4,4,8,-12,12,8,5,5,12,-7,9,4,-12,-1,2,5,4,7,-2,8,-12,-15,-1,2,-11]
Output:117个解
* Author: LKJ
* Date:2016/7/29
* Hint:遍历所有组合一一比较会超时,遍历其中一个元素,另外两个二分查找左右逼近
*/
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>

using namespace std;

/*
//单纯遍历,当数组大的时候会超时
class Solution {
public:
vector< vector<int> > threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
int len = nums.size();
vector<int> preAns;
vector< vector<int> > ans;
for(int i = 0; i < len-2; i++){
for(int j = i+1; j < len-1; j++){
for(int k = j+1; k < len; k++){
if((nums[i] + nums[j] + nums[k]) == 0){
if(nums[k] < 0) break;
preAns.clear();
preAns.push_back(nums[i]);
preAns.push_back(nums[j]);
preAns.push_back(nums[k]);
//避免重复
int flag = 0;
for(int m = 0; m < ans.size(); m++){
if(ans[m] == preAns){
flag = 1;
break;
}
}
if(flag == 0){
ans.push_back(preAns);
}
}
}
}
if(nums[i] > 0)  break;
}
return ans;
}
};*/

//输入113个数,耗时0.428s,仍然超时,在此基础上修改,需要减枝,跳过重复元素,剪掉了大部分循环,终于AC了
class Solution {
public:
vector< vector<int> > threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
int len = nums.size();
int zeronum = 0;
vector<int> preAns;
vector< vector<int> > ans;

for(int i = 0; i < len-1; i++){
if(nums[i] == 0){
zeronum = i;
break;
}
if((nums[i-1] < 0) && nums[i+1] > 0){
zeronum = i;
break;
}
}
for(int i = 0; i <= zeronum; i++){
if(i > 0 && nums[i] == nums[i - 1]) continue; // 跳过重复元素
for(int j = len-1; j >= zeronum; j--){//i,j相等的情况不会出现,因为k总是介于他们之间
if(j < len-1 && nums[j] == nums[j + 1]) continue; // 跳过重复元素
for(int k = i+1; k < j; k++){
if(k > i+1 && nums[k] == nums[k - 1]) continue; // 跳过重复元素
if((nums[i] + nums[j] + nums[k]) == 0){
preAns.clear();
preAns.push_back(nums[i]);
preAns.push_back(nums[k]);
preAns.push_back(nums[j]);

ans.push_back(preAns);
}
}
}
}
return ans;
}
};

int main(){
int myarr[113] = {8,5,12,3,-2,-13,-8,-9,-8,10,-10,-10,-14,-5,-1,-8,-7,-12,4,4,10,-8,0,-3,4,11,-9,-2,-7,-2,3,-14,-12,1,-4,-6,3,3,0,2,-9,-2,7,-8,0,14,-1,8,-13,10,-11,4,-13,-4,-14,-1,-8,-7,12,-8,6,0,-15,2,8,-4,11,-4,-15,-12,5,-9,1,-2,-10,-14,-11,4,1,13,-1,-3,3,-7,9,-4,7,8,4,4,8,-12,12,8,5,5,12,-7,9,4,-12,-1,2,5,4,7,-2,8,-12,-15,-1,2,-11};
vector<int> myin(myarr,myarr+113);

vector< vector<int> > myout;
Solution SA;

myout = SA.threeSum(myin);

cout<<"VecOUT:"<<myout.size()<<endl;
for(unsigned int i = 0; i < myout.size(); i++){
for(vector<int>::iterator itt = myout[i].begin() ;itt!=myout[i].end();itt++){
cout<<*itt<<"     ";
}
cout<<endl;
}
cout<<endl;

cout<<endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 遍历