三数之和
一、暴力法
如果利用三层fo循环去找所有满足条件的元组,则会出现相同的元素列表。比如[1,-1,0] 和 [-1,1,0]。这就需要再次进行去重操作,时间复杂度很大O(n3)。
二、双指针 + 排序
详解
问题1 : 如何去重?
这里有两个地方进行去重操作,一个是遍历元素的时候,一个是移动指针的时候。两个地方都要考虑到
问题2:双指针如何设置更加方便? 见代码
var threeSum = function(nums) {
// 长度是常数
const n = nums.length;
let result = [];
// 当元素少于3的时候,返回空
if(nums == null || n < 3) return result;
// 元素进行升序排列,这样可以根据相加结果进行移动.注意js中sort的写法
nums.sort((a,b) => a - b);
// 第一个值大于0,可以不考虑
if (nums[0] > 0) return result;
// i指向当前元素(固定),进行遍历。L指向下一个元素,R指向最后一个元素。每次循环根据相加结果分别移动L和R
for(let i=0;i<n;i++){
// 进行第一次去重操作,判断i当前元素是否重复。重复就结束这次循环,开启下一次循环。
if (i > 0 && nums[i] == nums[i-1]) continue;
let L = i + 1;
let R = n - 1;
while(L < R){
const sum = nums[i] + nums[L] + nums[R];
// 和为0时
if(sum == 0){
result.push([nums[i],nums[L],nums[R]]);
// 第二次去重操作。当和为0的时候,防止L和R的重复元素出现
while(L < R && nums[L] == nums[L+1]) L++;
while(L < R && nums[R] == nums[R-1]) R--;
// 和为0,移动L和R指针
L++;
R--;
}
// 和不为0,移动L和R,使得和为0.
// 大于0,代表大于0的值太大了,需要调小
else if(sum > 0) R--;
else if(sum < 0) L++;
}
}
return result;
};
三、js中基础知识
1、元素排序sort
// sort需要自定义排序方法
nums.sort((a,b) => a - b);
2、短语句的写法
// 常规写法
if(n > 3){
return [];
}
// 简洁写法
if(n > 3) return [];