Sansanowa
Given an array nums containing n integers, determine whether there are three elements a, b, c in nums, such that a + b + c = 0? Please find all triples that meet the conditions and are not repeated.
Note: The answer cannot contain repeated triples.
Example:
Given the array nums = [-1, 0, 1, 2, -1, -4],
The set of triples that meet the requirements is:
[
[-1, 0, 1],
[-1, -1, 2]
]
Source: LeetCode
Link: https://leetcode-cn.com/problems/3sum
Copyright is owned by LeetCode . For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
I got stuck with this question for a day, spent a long time on the heavy card, and stuck for another half day beyond the time limit. So I decided it was necessary to record it.
Looking at this painful record, there are two words between the lines: a~tui! Little chicken! !
My first idea was to sort the array from small to large, then fix nums[i] unchanged, and then assign nums[i+1] to nums[l], the last digit nums[nums.length-1] Assign value to nums[r], calculate the sum sum of three numbers nums[i], nums[l] and nums[r] to determine whether it is 0, and add it to the result set when it is satisfied. When sum <0, l++; When sumsum> 0, r-
my code at the time was like this
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function(nums) {
var t=[];
nums.sort((a, b) => a - b);
for(let i=0;i<nums.length;i++){
let l=i+1;
r=nums.length-1;
while(l<r){
if(nums[i]+nums[l]+nums[r]==0){
t.push([nums[i],nums[l],nums[r]]);
l++; r--;
}
else if(nums[i]+nums[l]+nums[r]<0){l++;}
else{r--;}
}
}
return t;
};
Then I found that I didn't consider deduplication, and the output result was like this:
So I thought of using Set to deduplicate. At this time, my code is like this:
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function(nums) {
var t=[];
nums.sort((a, b) => a - b);
for(let i=0;i<nums.length;i++){
let l=i+1;
r=nums.length-1;
while (nums[i] === nums[++i]) {}
while(l<r){
if(nums[i]+nums[l]+nums[r]==0){
t.push([nums[i],nums[l],nums[r]]);
l++; r--;
}
else if(nums[i]+nums[l]+nums[r]<0){l++;}
else{r--;}
}
}
var newArr = new Set(t);
var arr1 = [...newArr];
return arr1;
};
Then I found that the results did not change, I was puzzled. Later, after searching on Baidu and asking questions to the big guys, I learned that the set method is to judge the memory address, not the object value. Well, it really is my rookie.
Then, after referring to the logic of others, I changed the code to this:
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function(nums) {
var t=[];
nums.sort((a, b) => a - b);
for(let i=0;i<nums.length;i++){
if (nums[i] > 0) break;
if (i > 0 && nums[i] === nums[i - 1]) continue;//去重
let l=i+1;
r=nums.length-1;
while(l<r){
if(nums[i]+nums[l]+nums[r]==0){
t.push([nums[i],nums[l],nums[r]]);
while (l < r && nums[l] === nums[l + 1]) l++;//去重
while (l < r && nums[r] === nums[r - 1]) r--;//去重
l++; r--;
}
else if(nums[i]+nums[l]+nums[r]<0){l++;}
else{r--;}
}
}
return t;
};
So it passed! In addition, a solution of a big guy is included. At this time, I will put an advertisement for the big guy (public account: talk about the big front end, there are powerful deductions for the solution of each weekly contest, all using JavaScript, which is more friendly to front-end people):
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function(nums){
var t=[];
var i=0;
var len=nums.length;
nums.sort((a, b) => a - b);
const record = new Set();
while(i<len)
{
if(nums[i]>0) break;
let l=i+1;
r=len-1;
while(l<r){
var sum=nums[i]+nums[l]+nums[r];
if(sum==0){
const key=[nums[i],nums[l],nums[r]].sort().join(',');
if (!record.has(key)) {
t.push([nums[i],nums[l],nums[r]]);
record.add(key);}
l++; r--;
}
else if(sum<0){l++;}
else{r--;}
i++;
}
}
return t;
};
But this is beyond the time limit, I don’t know if anyone has a way to optimize this, please point it out!