我有一个似乎通过大多数测试的解决方案,但速度太慢。如果我没有弄错的话,由于三个for循环,复杂度为O(n ^ 3)。
我的想法是从i,j和k处的数组的前三个位置开始,将它们相加,看看它是否加起来为0.
功能目标是:
给定n个整数的数组nums,nums中是否有元素a,b,c,a + b + c = 0?找到数组中所有唯一的三元组,它们总和为零。
注意: 解决方案集不得包含重复的三元组。
示例:
给定数组nums = [-1, 0, 1, 2, -1, -4]
,
解决方案集是:
[
[-1, 0, 1],
[-1, -1, 2]
]
var threeSum = function(nums) {
var originalArray = nums
var lengthArray = nums.length
//sort array smallest to largest
nums.sort(function(a,b) {
return a-b
})
function arrayEqual(array1, array2){
var equal = false
array1.forEach((value1) => {
if(array1 === array2){
equal = true
}
})
return equal
}
var sum = 0;
var answerArray = [];
//start from first digit and add from there
for(var i = 0; i<lengthArray; i++){
for(var j = i+1; j<lengthArray; j++){
for(var k = j+1; k<lengthArray; k++){
if((nums[i]+nums[j]+nums[k] === 0)){
if(!arrayEqual(answerArray, [nums[i],nums[j],nums[k]])){
answerArray.push([nums[i],nums[j],nums[k]])
}
}
}
}
}
return Array.from(new Set(answerArray.map(JSON.stringify)), JSON.parse)
};
如何使用三个for循环来完成这项工作(又如何优化此解决方案?)
答案 0 :(得分:2)
以这种方式思考这个问题。从数组中选择任意数字k
。现在,您需要在数组中找到另外两个添加到-k
的数字。得到的三个数字之和为k + (-k) = 0
。
所以这个问题减少了,在数组中找到两个数字,如果给定的数组被排序,则使用两个指针方法将O(n)
添加到给定的数字。
简而言之,对数组进行排序,逐个获取每个数字(k)(O(n))
,找到另外两个数字,其中总和为-k (O(n))
。
总时间复杂度:O(n)* O(n)= O(n 2 )
答案 1 :(得分:1)
您可以在O(n^2)
的运行时中解决问题。这是使用JavaScript的解决方案
var threeSum = function(nums) {
var solutions = [];
var target = 0;
nums.sort(function(a, b) {
return a - b;
});
for(var i = 0; i < nums.length - 2; i++) {
if(i === 0 || (i > 0 && nums[i] !== nums[i - 1])) {
var lo = i + 1;
var hi = nums.length - 1;
var sum = - nums[i];
while(lo < hi) {
if(nums[lo] + nums[hi] === sum) {
solutions.push([nums[i],nums[lo],nums[hi]]);
while (lo < hi && nums[lo] === nums[lo + 1]) lo++;
while (lo < hi && nums[hi] == nums[hi-1]) hi--;
lo++; hi--;
}else if (nums[lo] + nums[hi] > sum) {
hi--;
}else {
lo++;
}
}
}
};
return solutions;
}