# 15. 三数之和
# 题目描述
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/3sum 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
# 我的回答
# 解法一
# 时空复杂度
时间复杂度:O(n^2) 排序 sort nlogn + 双层遍历 n^2 => n^2
空间复杂度: O(1)
var threeSum = function (nums) {
let res = []
if (nums.length < 3) return []
nums.sort((a, b) => a - b)
for (let i = 0; i < nums.length; i++) {
if (nums[i] > 0) continue
let left = i + 1
let right = nums.length - 1
let target = 0 - nums[i]
while (left < right) {
const leftCarry = nums[left]
const rightCarry = nums[right]
const sum = leftCarry + rightCarry
if (sum === target) res.push([nums[i], leftCarry, rightCarry])
if (sum <= target) while (left < right && nums[left] == leftCarry) left++
if (sum >= target) while (left < right && nums[right] == rightCarry) right--
}
while (i < nums.length - 1 && nums[i] == nums[i + 1]) i++
}
return res
};
# 解法二
# 时空复杂度
时间复杂度:O(n^2)
空间复杂度: O(1)
看了眼题解 可以抽离出来 后面可以做递归 nSum
var twoSumTarget = function (arr, start, target) {
let left = start
let right = arr.length - 1
let res = []
while (left < right) {
let leftCarry = arr[left]
let rightCarry = arr[right]
let sum = leftCarry + rightCarry
if (sum === target) res.push([nums[i], leftCarry, rightCarry])
if (sum <= target) while (left < right && nums[left] == leftCarry) left++
if (sum >= target) while (left < right && nums[right] == rightCarry) right--
}
return res
}
var threeSum = function (nums) {
nums.sort((a, b) => a - b)
let res = []
for (let i = 0; i < nums.length; i++) {
if (nums[i] > 0) continue
let data = twoSumTarget(nums, i + 1, 0 - nums[i])
data.forEach(v => res.push([nums[i], ...v]))
while (i < nums.length - 1 && nums[i] == nums[i + 1]) i++
}
return res
};