leetcode 15.三数之和

题目描述:

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

思路分析:

面试中常常出现的3sum问题,和2sum是比较类似的。但这里由于是三个数的和为0,因此首先需要固定一个数,再在其后续的序列中利用2sum的方法。由于题目要求不可包含重复的三元组,因此需要进行一些过滤。首先对数组进行排序,判断当前元素是否大于0,若大于0,则不可能与后续的元素组成三元组,直接退出。若当前的元素与前一个元素相等,表示重复,跳过本轮循环。此外,在twoSum函数中,也需要进行判断,若当前left值与前一位相等,则重复,跳过;同理当前right值与后一位相等,则重复,跳过。算法复杂度为O(n^2)。

代码:

 1 class Solution {
 2 public:
 3     void twoSum(vector<vector<int>>&res, vector<int>& nums, int cur)
 4     {
 5         int left = cur+1;
 6         int right = nums.size()-1;
 7         while(left<right && left>cur && right<nums.size())
 8         {
 9             int sum = nums[left]+nums[cur]+nums[right];
10             if(sum > 0)
11                 right--;
12             else if(sum < 0)
13                 left++;
14             else
15             {
16                 if(left==cur+1 || right==nums.size()-1)
17                 {
18                     res.push_back(vector<int>{nums[cur], nums[left], nums[right]});
19                     left++;
20                     right--;
21                 }
22                 else if(nums[left]==nums[left-1])
23                     left++;
24                 else if(nums[right] == nums[right+1])
25                     right--;
26                 else
27                 {
28                     res.push_back(vector<int>{nums[cur], nums[left], nums[right]});
29                     left++;
30                     right--;
31                 }
32             }
33         }
34     }
35     vector<vector<int>> threeSum(vector<int>& nums) {
36         vector<vector<int>> res;
37         if(nums.size()<3)
38             return res;
39         sort(nums.begin(), nums.end());
40         for(int i=0; i<nums.size(); i++)
41         {
42             if(nums[i]>0)
43                 break;
44             if(i>0 && nums[i]==nums[i-1])
45                 continue;
46             twoSum(res, nums, i);
47         }
48         return res;
49     }
50 };
原文地址:https://www.cnblogs.com/LJ-LJ/p/11317535.html