给定一个包含 n 个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]
题目标签:Array / Two Pointers
题目链接:LeetCode / LeetCode中国
首先先将数组排序,然后利用双指针进行夹逼。
对于本问题,先将数组排序,对于每个不重复的数,在其右侧的数里找两个和为该数相反数的组合,从而把问题转化为从有序数组里找和为某个值的组合。可以使用双指针夹逼,具体做法为:
设i
和j
初始为头部和尾部。当两个位置的数和为目标值时,范围向中间收缩(也就是i++
,j--
);如果和大于目标值,j--
;如果和小于目标值,i++
。直到i>=j
。
如何判断二元组不重复呢?只需要判断是否与最后一个一样就行。
Language | Runtime | Memory |
---|---|---|
cpp | 120 ms | 4.2 MB |
class Solution {
public:
vector<vector<int>> twoSum(vector<int>& nums, int target, int st, int ed, bool uniq) {
vector<vector<int> > res;
while (st < ed) {
if (nums[st] + nums[ed] == target) {
if (!uniq || res.empty() || res.back()[0] != nums[st]) {
res.push_back(vector<int>{nums[st], nums[ed]});
}
++st;
--ed;
} else if (nums[st] + nums[ed] > target) {
--ed;
} else {
++st;
}
}
return res;
}
vector<vector<int>> nSum(vector<int>& nums, int target, int st, int ed, int n, bool uniq) {
vector<vector<int> > res;
if (n < 1) { return res; }
else if (n == 1) {
if(nums.end() != find(nums.begin(), nums.end(), target)) {
res.push_back(vector<int>{target});
return res;
}
}
else if (n == 2) {
return twoSum(nums, target, st, ed, uniq);
} else {
for (int i=st; i<=ed; ++i) {
int num = nums[i];
if (!uniq || res.empty() || res.back()[0] != num) {
auto ret = nSum(nums, target-num, i+1, nums.size()-1, n-1, uniq);
for (auto r : ret) {
vector<int> tmp;
tmp.push_back(num);
tmp.insert(tmp.end(), r.begin(), r.end());
res.push_back(tmp);
}
}
}
return res;
}
}
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nSum(nums, 0, 0, nums.size()-1, 3, true);
}
};
Language | Runtime | Memory |
---|---|---|
python3 | 1200 ms | N/A |
class Solution:
def twoSum(self, nums, target):
res = []
nums.sort()
i, j = 0, len(nums) - 1
while i < j:
if nums[i] + nums[j] == target:
if not res or res[-1][0] != nums[i]:
res.append([nums[i], nums[j]])
i += 1
j -= 1
elif nums[i] + nums[j] > target:
j -= 1
else:
i += 1
return res
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
nums.sort()
tmp = set()
for i, num in enumerate(nums):
if num not in tmp:
for twosum in self.twoSum(nums[i+1:], -1 * num):
res.append([num, twosum[0], twosum[1]])
tmp.add(num)
return res