题目描述:
给定一个包含 n 个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]
1.暴力解法,低效率
将数组排序 2.定义三个指针,i,j,k。遍历i,那么这个问题就可以转化为在i之后的数组中寻找nums[j]+nums[k]=-nums[i]这个问题,也就将三数之和问题转变为二数之和---(可以使用双指针)时间复杂度O(n^3)
1 var threeSum = function(nums) { 2 nums.sort((a,b)=>{ return a - b }) // 先排序 3 var arr = [], len = nums.length; 4 if(nums === null) return []; 5 if(len < 3) return []; 6 for(var i = 0; i < len - 2; i++){
// 从数组的第二个元素开始,如果该元素和前一个值相同则结果肯定重复;因此需要去重,使用contine直接跳过本次循环进入下一次循环,
//(break则彻底破坏结束循环),因为所有元素排序过,所有相同的元素一定是挨着的。 7 if( i > 0 && nums[i] === nums[i-1]) continue; 8 for(var j = i + 1; j < len -1; j++){ // j从当前元素的下一个元素开始取 9 if(j > i + 1 && nums[j] === nums[j-1]) continue; 10 for(var k = j + 1; k < len; k++){ 11 if(k > j + 1 && nums[k] === nums[k-1]) continue; 12 if(nums[i] + nums[j] + nums[k] === 0) 13 arr.push([nums[i],nums[j],nums[k]]); 14 } 15 } 16 } 17 return arr; 18 };
2.先排序,再用二分法
1 var threeSum = function(nums) { 2 nums = nums.sort((a,b) => a-b); 3 var res = []; 4 for(var i=0; i<nums.length;i++){ 5 if(i==0 || nums[i]>nums[i-1]) { 6 var left = i+1; 7 var right = nums.length - 1; 8 while(left < right) { 9 var s = nums[i]+nums[left]+nums[right]; 10 if(s == 0) { 11 res.push([nums[i],nums[left++],nums[right--]]); 12 while(nums[left] == nums[left-1]) { 13 left++; 14 } 15 while(nums[right] == nums[right+1]) { 16 right--; 17 } 18 } else if(s > 0) { 19 right--; 20 while(nums[right] == nums[right+1]) { 21 right--; 22 } 23 } else { 24 left++; 25 while(nums[left] == nums[left-1]) { 26 left++; 27 } 28 } 29 } 30 } 31 } 32 return res; 33 }
3.先排序,然后存起来
1 var threeSum = function(nums) { 2 nums=nums.sort(function(a,b){return a-b}); // 先排序 3 var i=0; 4 var arr=[]; 5 while(i<nums.length-1){ 6 var a=nums[i],j=i+1,k=nums.length-1; 7 while(j<k){ 8 var b=nums[j],c=nums[k]; 9 var sum=a+b+c; 10 if(sum==0)arr.push([a,b,c]); // 存起来 11 if(sum<=0) 12 while(nums[j]==b&&j<k)j++; // 第2个数 13 if(sum>=0) 14 while(nums[k]==c&&j<k)k--; // 最后一个数 15 } 16 while(nums[i]==a&&i<nums.length-1)i++; // 第一个数 17 } 18 return arr; 19 };
4.评论区低效率答案
var threeSum = function(nums) { nums.sort(function(a,b){ return a-b; }) console.log(nums) var arr=[] arr = noZero(nums,arr) return arr }; var noZero=function(nums,a){ var arr = a,flag = false for(var m =0;m<nums.length;m++){ if(m==0||nums[m]>nums[m-1]){ var i=m+1,l=nums.length-1 while(i<l){ //循环 var s=nums[m]+nums[i]+nums[l] if(s===0){ arr.push([nums[i],nums[l],nums[m]]) i++ l-- while(i<l&&nums[i]===nums[i-1]){ i++ } while(i<l&&nums[l]===nums[l+1]){ l-- } }else if(s>0){ l-- }else { i++ } } } } return arr };