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 };
这个是带剪枝版本的,两段剪枝