1 static int wing=[]()
 2 {
 3     std::ios::sync_with_stdio(false);
 4     cin.tie(NULL);
 5     return 0;
 6 }();
 7 
 8 class Solution 
 9 {
10 public:
11     vector<vector<int>> threeSum(vector<int>& nums) 
12     {
13         vector<vector<int>> res;
14         int sz=nums.size();
15         sort(nums.begin(),nums.end());
16         int target,left,right,sum;
17         for(int i=0;i<sz;i++)
18         {
19             if(nums[i]>0)
20                 break;
21             if(i>0&&nums[i-1]==nums[i])
22                 continue;
23             target=-nums[i];
24             left=i+1;
25             right=sz-1;
26             while(left<right)
27             {
28                 sum=nums[left]+nums[right];
29                 if(sum==target)
30                 {
31                     res.push_back({nums[i],nums[left],nums[right]});
32                     left++;
33                     while(left<right&&nums[left]==nums[left-1])
34                         left++;
35                     right--;
36                     while(left<right&&nums[right]==nums[right+1])
37                         right--;
38                 }
39                 else if(sum<target)
40                     left++;
41                 else
42                     right--;
43             }
44         }
45         return res;
46     }
47 };

先排序,以一个元素为扫描基准,在该元素右侧查找两个元素,使得这两个元素的和为当前扫描元素的相反数。将三和问题转化为二和问题,时间复杂度O(n²)

 1 class Solution {
 2 public:
 3     vector<vector<int>> threeSum(vector<int>& nums) {
 4         vector<vector<int>> res;
 5         int sz=nums.size();
 6         if(sz<3)
 7             return res;
 8         sort(nums.begin(), nums.end());
 9         int left,right,sum2,cursum2;
10         int test=nums[sz-1]+nums[sz-2];
11         int lim=sz-2;
12         for(int i=0;i<lim;i++){
13             if(nums[i]>0)
14                 return res;
15             if(i>0&&nums[i]==nums[i-1])
16                 continue;
17             if(nums[i]+test<0)
18                 continue;
19             if(nums[i]+nums[i+1]+nums[i+2]>0)
20                 return res;
21             sum2=-nums[i];
22             left=i+1;
23             right=sz-1;
24             while(left<right){
25                 cursum2=nums[left]+nums[right];
26                 if(cursum2==sum2){
27                     res.push_back({nums[i],nums[left],nums[right]});
28                     ++left;
29                     while(left<right&&nums[left]==nums[left-1])
30                         ++left;
31                     --right;
32                     while(left<right&&nums[right]==nums[right+1])
33                         --right;
34                 }
35                 else if(cursum2<sum2)
36                     ++left;
37                 else
38                     --right;
39             }
40         }
41         return res;
42     }
43 };

这个是带剪枝版本的,两段剪枝

posted on 2018-07-04 12:47  高数考了59  阅读(132)  评论(0)    收藏  举报