Q:
题目链接:3Sum
先看题目要求:
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note: The solution set must not contain duplicate triplets.
For example, given array S = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
提供一个元素为整数的数组S,寻找出所有的包含三个元素的子数组,使得这三个元素的和为0,并且结果中不能有重复的子数组。
分析
暴力解法是不太可能了,至少要一个O(n3)的解法,所以放弃…由于本题的结果和元素的大小息息相关,所以想到将数组排序后再求解会简单一些。排序后,需要考虑如何找出所有的“三胞胎”子元素数组?首先循环确定一个,然后再剩下的元素中选择头尾两个,根据和的大小来决定指针的移动。看代码:
A:
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function(nums) {
var result = [];
//不足三个元素,返回空
if(nums.length < 3){
return result;
}
//先顺序排列(从小到大)
nums = nums.sort(function(a,b){return a-b})
//由于是升序排列,如果第一个元素就比0大,那一定找不到符合要求的数组了
if(nums > 0){
return result;
}
for(var i = 0;i < nums.length - 2;i++){
//去掉重复的结果
if (i > 0 && nums[i] === nums[i - 1]) {
continue;
}
var left = i+1;
var right = nums.length - 1;
while(left < right){
var sum = nums[i] + nums[left] + nums[right];
if(sum === 0){
result.push([nums[i],nums[left],nums[right]])
left++;
right--;
//去掉重复的结果,直接将指针移到不相同的元素上面
while(left < right && nums[left] === nums[left - 1]){
left++;
}
while(left < right && nums[right] === nums[right + 1]){
right--;
}
}else if(sum > 0){
right--;
}else{
left++;
}
}
}
return result;
};
代码还算简单,需要注意的地方已经在注释中标出,尤其注意去重的操作。