题:一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三元组
题解:
先将数组进行排序
从左侧开始,选定一个值为 定值 ,右侧进行求解,获取与其相加为 00 的两个值
类似于快排,定义首和尾
首尾与 定值 相加
等于 0,记录这三个值
小于 0,首部右移
大于 0,尾部左移
定值右移,重复该步骤
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function(nums) {
if(!nums || nums.length<3)return [];
let result = [];
nums = nums.sort((a,b) => a-b);
for(let i = 0;i<nums.length;i++){
if(i && nums[i] === nums[i-1]) continue; // 与上一个数相等,跳过循环。
let left = i+1; // 左指针
let right = nums.length-1; // 右指针
while(left < right) {
let sum = nums[i] + nums[left] + nums[right]; // 三数之和
if(sum > 0){
right--;
}else if(sum < 0){
left++;
}else {
result.push([nums[i],nums[left++],nums[right--]]); // 存入数组,left++,right--;
while(nums[left] === nums[left-1]){ // 跳过重复值
left++;
}
while(nums[right] === nums[right+1]){ // 跳过重复值
right--;
}
}
}
}
return result;
};
题:最接近的三数之和,一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在恰好一个解。
题解:
双指针解法:
数组先升序排序,初始化一个最小和
遍历数组,定义双指针,如果当前和更接近,更新最小值
根据当前三数之和和target的关系,移动指针
若在遍历过程中,三数之和等于target,直接返回当前的和即可
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var threeSumClosest = function(nums, target) {
nums = nums.sort((a,b) => a-b); // 排序
let min = Infinity;
for(let i = 0;i < nums.length; i++){
let [left,right] = [i+1,nums.length-1];
while(left < right) {
let sum = nums[i] + nums[left] +nums[right];
if(Math.abs(sum - target) < Math.abs(min - target)){
min = sum;
}
if(sum > target){ // 根据sum和target的关系,移动指针
right--
}else if(sum < target){
left++;
}else {
return sum; // 相等直接返回;
}
}
}
return min;
};