自己的原先暴力解法
自己的题解(全部超时):
/*** @param {number[]} nums* @return {number[][]}*/var threeSum = function(nums) {const sumArr = [];if(nums.length<3){return []}// 暴力 超时// let len = nums.length;// for(let i = 0 ; i < len ; i++ ){// for(let j = i +1 ; j < len ; j++ ){// for(let z = j + 1 ; z < len ; z++ ){// if(nums[i] + nums[j] + nums[z] === 0 && [nums[i] , nums[j] , nums[z]].sort()){// let sum = [nums[i] , nums[j] , nums[z]].sort()// if(sumArr.every(c=>`${c}`!==`${sum}`))// sumArr.push(sum)// }// }// }// }// 暴力,不让过// const _nums = nums.sort((a,b)=>a-b);//排序// const len = _nums.length// console.log(_nums,len);// let maxIndex = len - 1;// for(let i = 0 ; i < len-2 ; i++ ){// if(_nums[i]>0){// break// }// if(_nums[i]+_nums[maxIndex -1] +_nums[maxIndex ]<0){// continue// }// for(let j = i + 1; j < len-1 ; j++ ){// if(_nums[i]+_nums[j] > 0 ){// break// }// if(_nums[i]+_nums[j] +_nums[maxIndex ]<0){// continue// }// for(let z = j +1 ; z < len ; z++ ){// if(_nums[i] + _nums[j] + _nums[z] > 0 ){// break// }// if(_nums[i] + _nums[j] + _nums[z] === 0 ){// let sum = [_nums[i] , _nums[j] , _nums[z]]// if(sumArr.every(c=>`${c}`!==`${sum}`))// sumArr.push(sum)// }// }// }// }//const _nums = nums.sort((a,b)=>a-b);//排序const len = _nums.length;const arr1 = {}for(let i = 1;i < len - 1 ; i++ ){for(let j = len - 1;j > i ; j-- ){const sum = _nums[i] +_nums[j]// console.log(sum,i,j,_nums[i] ,_nums[j])if(sum<0){break;}let arr = arr1[sum];const key= `${[_nums[i],_nums[j]]}`if(arr){// if(_nums[i]===_nums[arr[len1-1][0]]&&_nums[j]===_nums[arr[len1-1][1]]&&)arr[key] = [i,j]}else {arr1[sum] = {[key]:[i,j]}}}}console.log(arr1,_nums)for(let i = 0;i < len - 2 ; i++ ){const first = arr1[-_nums[i]]if(first ){for(let k in first){const c= first[k]if(c[0]>i){const a = [_nums[i]].concat(c.map(cc=>_nums[cc]))if(sumArr.every(c=>`${c}`!==`${a}`))sumArr.push(a)}}// arr1[-_nums[i]].forEach(c=>{// if(c[0]>i){// const a = [_nums[i]].concat(c.map(cc=>_nums[cc]))// if(sumArr.every(c=>`${c}`!==`${a}`))// sumArr.push(a)// }// })}}return sumArr};
双指针
「双指针」,当我们需要枚举数组中的两个元素时,如果我们发现随着第一个元素的递增,第二个元素是递减的,那么就可以使用双指针的方法,将枚举的时间复杂度从 O(N^2)减少至 O(N)O(N)。为什么是 O(N) 呢?这是因为在枚举的过程每一步中,「左指针」会向右移动一个位置,而「右指针」会向左移动若干个位置,这个与数组的元素有关,但我们知道它一共会移动的位置数为 O(N),均摊下来,每次也向左移动一个位置,因此时间复杂度为 O(N)
正确的解法
/*** @param {number[]} nums* @return {number[][]}*/var threeSum = function(nums) {let sumArr = [];if(nums.length<3){return []}// 全是0过不了if(Array.from(new Set(nums)).length===1&&nums[0]===0){return [[0,0,0]]}// 暴力 超时let len = nums.length;const _nums = nums.sort((a,b)=>a-b);//排序for(let i = 0 ; i < len - 2 ; i++ ){if(_nums[i]>0){break}if(_nums[i]+_nums[len - 2] +_nums[len - 1 ]<0){continue}for(let j = i +1 ; j < len - 1; j++ ){if(_nums[i]+_nums[j] >0){break;}if(_nums[i]+_nums[j] +_nums[len - 1 ]<0){continue}let preZ = len - 1for(let z = len - 1 ; z > j ; z-- ){if(_nums[i] + _nums[j] + _nums[z] === 0 ){let sum = [_nums[i] , _nums[j] , _nums[z]]// if(sumArr.every(c=>`${c}`!==`${sum}`))sumArr.push(JSON.stringify(sum));preZ = z - 1;// while(_nums[preZ]===_nums[z]){// preZ--// }break}}}}sumArr = Array.from(new Set(sumArr)).map(c=>JSON.parse(c))return sumArr};
