15. 三数之和中等
题目
**给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] ** 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
- 输入:nums = [-1,0,1,2,-1,-4]
- 输出:[[-1,-1,2],[-1,0,1]]
- 解释: -- nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。 -- nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。 -- nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
- 不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
- 注意,输出的顺序和三元组的顺序并不重要。
示例 2:
- 输入:nums = [0,1,1]
- 输出:[]
- 解释:唯一可能的三元组和不为 0 。
示例 3:
- 输入:nums = [0,0,0]
- 输出:[[0,0,0]]
- 解释:唯一可能的三元组和为 0 。串。
提示:
- 3 <= nums.length <= 3000
- -105 <= nums[i] <= 105
思路
实现
1、第一种方式
/**
* @param {string} nums
* @return {number}
*/
var threeSum = function (nums) {
let arr = [];
let threeArr = [];
for (let i = 0; i < nums.length - 2; i++) {
let j = i + 1;
let k = j + 1;
while (k < nums.length && j < nums.length - 1) {
if (nums[i] + nums[j] + nums[k] == 0) {
threeArr = sortArr([nums[i], nums[j], nums[k]]);
let flag = arr.every((m) => m.toString() != threeArr.toString());
if (flag) arr.push(threeArr);
}
if (k == nums.length - 1) {
j++;
k = j + 1;
} else {
k++;
}
}
;
}
return arr;
}
var sortArr = function (arr) {
return arr.sort((a, b) => a - b);
};
2、第二种方式
var threeSum = function (nums) {
let arr = [];
const len = nums.length;
if (nums == null || len < 3) return arr;
nums.sort((a, b) => a - b);
for (let i = 0; i < len - 2; i++) {
if (nums[i] > 0) break; // 因为已经排序过,所以如果首位大于零了,后面所有都会大于零,可以直接跳出循环
if (i > 0 && nums[i] == nums[i - 1]) continue; // 去重
let L = i + 1; // 左指针
let R = len - 1; // 右指针
while (L < R) {
const sum = nums[i] + nums[L] + nums[R];
if (sum == 0) {
arr.push([nums[i], nums[L], nums[R]]);
while(nums[L] == nums[L+1] ) L++;
while(nums[R] == nums[R-1] ) R--;
L++;
R--;
}
else if (sum < 0) L++;
else if (sum > 0) R--;
}
}
return arr;
};
var sortArr = function (arr) {
return arr.sort((a, b) => a - b);
};