本题来自于leetcode, 以下为题目:
给定一个包含 n 个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]
分析:原本所用为双层for循环,但在第311个测试时,由于测试示例过长而超时,所以改变实现方法;
(1)、对数组进行排序,如果数组的第一个元素大于0或者最后一个元素小于0,则不可能出现和为0的情况;
(2)、首先选定一个元素(A),再利用双指针对数组的元素进行遍历,将一个指针指向A元素的后一个元素(B),另一个指针指向数组的最后一个元素(C);
(3)、判断B+C的结果是否是A的相反数,如果B+C > (-A) ,则使C指针向前移动,如果B+C < (-A) ,则使B指针向后移动;
(4)、如果B指针的元素与其前一个元素相等,则B指针向后移动一位;如果C指针与其后一个元素相等,则C指针向前移动一位;
以下为代码示例:
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function(nums) {
var result = new Array();
var len = nums.length;
var flag = 0;
var hash = {};
nums.sort((a, b) => {
return a-b;
});
if(nums[0] > 0 || nums[len - 1] < 0) return result;
for(var i = 0; i < len; i++){
if(nums[i] === nums[i-1]) continue;
flag = 0 - nums[i];
var start = i + 1, end = len - 1;
while(start < end){
var middle = new Array();
if(nums[start] + nums[end] < flag){
start ++;
} else if(nums[start] + nums[end] > flag){
end--;
} else {
middle.push(nums[i]);
middle.push(nums[start]);
middle.push(nums[end]);
if(!hash[middle]){
hash[middle] = true;
result.push(middle);
}
start += 1;
end -= 1;
while(start < end && nums[start] === nums[start - 1]){
start += 1;
}
while(start < end && nums[end] === nums[end + 1]){
end -= 1;
}
}
}
}
return result;
};