15. 三数之和
题目
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
来源:力扣(LeetCode)链接
思路
- 先对数组进行排序
- 遍历数组,枚举第一个数。 nums[first]
- 从第一个下一位开始枚举第二个数。 nums[second]
- 从数组最后开始枚举第三个数。 nums[third]
- 比较枚举出来的第二个数与第三个数之和与第一个数的取反。 nums[second] + nums[third] >? =? <? -nums[first]
- 如果第二个数与第三个数之和大于第一个数的取反,继续枚举第三个数。 nums[second] + nums[third] > -nums[first] => third = third - 1。因为数组进行了从小到大排序的,所以去左侧的找第三个数.
- 如果第二个数与第三个数之和等于第一个数的取反。 nums[second] + nums[third] == -nums[first] => 符合条件。
- 如果第二个数与第三个数之和小于第一个数的取反。 nums[second] + nums[third] < -nums[first] => 只能继续枚举second。
代码
C++
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
std::sort(nums.begin(), nums.end());
vector<vector<int>> ans;
for (int first = 0, n = nums.size(); first < n; first++) {
if (first > 0 && nums[first] == nums[first - 1])
continue;
for (int second = first + 1, third = n - 1; second < third; second++) {
if (second > first + 1 && nums[second] == nums[second - 1])
continue;
while (second < third && nums[second] + nums[third] > -nums[first])
third--;
if (second == third)
break;
if (nums[first] + nums[second] + nums[third] == 0)
ans.push_back({nums[first], nums[second], nums[third]});
}
}
return ans;
}
};
复杂度分析
- 时间复杂度: O(n2)
- 空间复杂度: O(1)