给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:[ [-1, 0, 1], [-1, -1, 2] ]
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function (nums) {
nums.sort((a, b) => a - b);//增序排列
let i = 0, lens = nums.length;
let res = [];
while (i < lens) {
if (nums[i] > 0) break; //一个负数都没有了,后面两个数比它大,3个数加起来必不可能为0
if (nums[i] === 0) {
//紧随其后的必然是两个0,否则不需要输出
if (nums[i + 1] === 0 && nums[i + 2] === 0) res.push([0, 0, 0]);
break;
}
let head = i + 1, tail = lens - 1;
if (head >= tail) break;
let target = 0 - nums[i];
do {
let sum = nums[head] + nums[tail];
if (sum === target) {
res.push([nums[i], nums[head], nums[tail]]);
//去掉重复值
while (nums[head] && nums[head + 1] && nums[head] === nums[head + 1]) head++;
//去掉重复值
while (nums[tail] && nums[tail - 1] && nums[tail - 1] === nums[tail]) tail--;
head++;
tail--;
} else if (sum > target) {
tail--;
} else {
head++;
}
} while (head < tail);
i++;
//同样的数字不用再输出一次重复解
while (nums[i] === nums[i - 1]) {
i++;
}
}
return res;
};
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4] 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var threeSumClosest = function (nums, target) {
nums.sort((a, b) => a - b);
let i = 0, lens = nums.length;
let res, minDistance = Number.MAX_VALUE;
while (i < lens - 2) {
let head = i + 1, tail = lens - 1;
while (head < tail) {
let sum = nums[i] + nums[head] + nums[tail];
let distance = Math.abs(sum - target);
if (distance < minDistance) {
minDistance = distance;
res = sum;
}
if (sum > target) {
tail--;
} else if (sum < target) {
head++;
} else {
//题目假设了只存在唯一答案
return target;
}
}
i++;
}
return res;
};