一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情。
也是跟着b站的一个老师在学,老师的声音好好听,好喜欢🥰~
题目
给出一个包含n个数组的nums,判断nums中是否存在三个元素a,b,c。使得a + b + c = 0,找出所有和为0且不重复的数组。
例:
输入: nums = [-1,0,1,2,-1,-4];
输出:[[-1,-1,2],[-1,0,1]];
输入:nums = [];
输出:[];
输入:nums = [0];
输出:[]
本题难点:在何时进行去重
题解及思路
1、给数据排序,乱序不方便相加的运算操作;
2、用for循环遍历数组,i从0遍历到nums.length - 2。为何要遍历到nums.length - 2呢?
原因是:因为题目需要返回的是三个元素相加等于0,那么就需要三个指针。如果遍历到nums.length - 1或nums.length ,那么就意味着start和end有一个或两个没有对应的值,那么就会出现越界问题。
3、如果当前数字i与前一个数字i - 1 相等则跳过。原因是题目中不允许出现重复的数组,而相同的数字已经和后面的start和end进行相加比较了,所以此数字不需要重复相加,故跳过。
4、如果数字不相同,则设置 start = i + 1, end = length - 1。查看i + start + end 与0相比较是大还是小。如果比0小,则start++;如果比0 大,则end--;如果等于0,则把这三个数字添加到数组里。
注意(解决上面问题在何时去重): 此时,还需要一个判断就是判断start与start-1是否相等,如果相等则start++向前一位;end也是一样的道理,要判断与end+1是否相等,相等则end--向前一位。
5、返回结果
至于为何不排完序就去重,可能会出现类似[-1, -1 ,2]的情况。
代码示例
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function(nums) {
let result = [];
nums.sort(function(a,b){ //对数组进行排序
return a - b;
})
for(let i = 0;i< nums.length - 2; i++) {
if (i === 0 || nums[i] !== nums[i -1]) { // 当前数字与前一个数字不相等
let start = i + 1, end = nums.length - 1;
while(start < end) { // 确保没有越界
if (nums[i] +nums[start] + nums[end] === 0) { // 如果三个数相加等于0
result.push([nums[i], nums[start], nums[end]]); // 则添加进数组
start++; // 向后移动
end--; // 向前移动
while(start < end && nums[start] === nums[start - 1]) { // start去重,相等则向后移动
start++;
}
while(start < end && nums[end] === nums[end + 1]) { // end去重,相等则向前移动
end--;
}
} else if (nums[i] +nums[start] + nums[end] < 0) {
start++; // 向后移动
} else { // 大于0
end--; // 向前移动
}
}
}
}
return result;
};