public List<List<Integer>> threeSum(int[] num) {
Arrays.sort(num);
List<List<Integer>> res = new LinkedList<>();
for (int i = 0; i < num.length-2; i++) {
if (i == 0 || (i > 0 && num[i] != num[i-1])) {
int lo = i+1, hi = num.length-1, sum = 0 - num[i];
while (lo < hi) {
if (num[lo] + num[hi] == sum) {
res.add(Arrays.asList(num[i], num[lo], num[hi]));
while (lo < hi && num[lo] == num[lo+1]) lo++;
while (lo < hi && num[hi] == num[hi-1]) hi--;
lo++; hi--;
} else if (num[lo] + num[hi] < sum) lo++;
else hi--;
}
}
}
return res;
}
我当前的javascript:
var mysort = function(a, b) {
return a - b;
}
var threeSum = function(ns) {
// everything is sorted
ns.sort(mysort);
// acc
let res = [];
// loop all #, but we keep last 2 elements
for (let i = 0; i < ns.length - 2; i++) {
// 1. i === 0, rm 1st element
// 2. same same skip
if (i === 0 || (i > 0 && ns[i] !== ns[i - 1])) {
//if (true) {
// the 2nd element
let lo = i + 1;
// the end element
let hi = ns.length - 1;
// remove the 1st element
let sum = 0 - ns[i];
// bi search
while (lo < hi) {
console.log(lo, hi, ns[lo], ns[hi], sum)
// bi search: 2nd element + end element === sum
if ((ns[lo] + ns[hi]) === sum) {
console.log('push');
res.push([ns[i], ns[lo], ns[hi]]);
// skip: lo < hi, lo skip equal
while (lo < hi && ns[lo] === ns[lo + 1]) lo++;
// skip: lo < hi, hi skip equal
while (lo < hi && ns[hi] === ns[hi - 1]) hi--;
// closer
lo++;
// closer
hi--;
} else if (ns[lo] + ns[hi] < sum)
lo++; // lo + hi < sum, lo++
else
hi--; // lo + hi > sum, hi--
}
}
return res;
}
}
console.log(threeSum([-1,0,1,2,-1,-4]));
无法通过第一个测试用例:
[-1,0,1,2,-1,-4]
答案 0 :(得分:1)
您的代码很好,但您放错了return
的位置:应该将其移出for
循环。
所以:
return res;
}
}
...应该是:
}
return res;
}
请注意,在JavaScript中,您无需防止超出范围的数组引用,因为它只会返回undefined
,它不等于任何数值。因此,您可以这样做:
if (ns[i] !== ns[i - 1])
即使在Java中,您也不需要执行此测试:i > 0 &&
,因为受shortcut evaluation的影响,它在求值时总是正确的。因此,在Java版本中,您可以执行以下操作:
if (i == 0 || num[i] != num[i-1]) {
答案 1 :(得分:0)
这是您问题的解决方案:
function threeSum(nums){
let len = nums.length;
if(len < 3) return [];
nums.sort(function(a,b){
return a-b;
})
if(nums[0] > 0 || nums[0] + nums[1] + nums[2] > 0) return [];
if(len === 3) {
if(nums[0] + nums[1] + nums[2] === 0) return [nums];
else return [];
}
//console.log(nums);
let result = [];
let checker = '';
for(let i=0; i<len-2; i++){
for(let j=i+1; j<len-1; j++){
//since the array is sorted, we only need to start from
//the last index that where value was found, since
//nums[k] has to be a lower number.
for(let start = len-1, k = start; k>i, k>j;) {
let triplet = [nums[i], nums[j], nums[k]];
let tripletString = '/' + nums[i] + ' ' + nums[j] + ' ' + nums[k] + '/';
if(nums[i] + nums[j] === -nums[k] && !checker.includes(tripletString)){
result.push(triplet);
checker += tripletString;
start--;
k = start;
} else {
k--;
}
}
}
}
return result;
}
var output = threeSum([-1,0,1,2,-1,-4]);
console.log(output);
答案 2 :(得分:0)
如果删除类型定义,则JavaScript中的实现几乎相同
function threeSum(num) {
// Arrays.sort(num);
num.sort((a, b) => a-b);
// List<List<Integer>> res = new LinkedList<>();
const res = [];
for (let i = 0; i < num.length-2; i++) {
if (i == 0 || (i > 0 && num[i] != num[i-1])) {
let lo = i+1, hi = num.length-1, sum = 0 - num[i];
while (lo < hi) {
if (num[lo] + num[hi] == sum) {
// push a new Array instead of .add List
res.push([num[i], num[lo], num[hi]]);
while (lo < hi && num[lo] == num[lo+1]) lo++;
while (lo < hi && num[hi] == num[hi-1]) hi--;
lo++; hi--;
} else if (num[lo] + num[hi] < sum) lo++;
else hi--;
}
}
}
return res;
}