y总在究极班讲的LeetCode
上三数之和、四数之和的解法是类似的:都是利用双指针算法将时间复杂度降低一维。所以可以给出一个k数之和
的通解,算法时间复杂度为O(n(k−1))
主要思想就是利用递归,将n一层层的降低,当n降到2的时候,就可以使用双指针来求解了。
如果在n为2的时候找到了解,要在递归函数退出的时候,把路径上的数都加入到解中,组成最终的答案。
function nSum(nums, target, n) {
if (n <= 1) return [];
nums.sort((a, b) => a - b);
return help(nums, target, n);
function help(nums, target, n, l = 0, r = nums.length) {
let ans = [];
if (n == 2) {
for (let i = l, j = r - 1; i < j; i++) {
if (i > l && nums[i] == nums[i - 1]) continue;
while (i < j && nums[i] + nums[j] > target) j--;
if (i < j && nums[i] + nums[j] == target) ans.push([nums[i], nums[j]]);
}
} else {
for (let i = l; i < r; i++) {
if (i > l && nums[i] == nums[i - 1]) continue;
let temp = help(nums, target - nums[i], n - 1, i + 1, r);
if (temp.length) {
temp.forEach(item => item.push(nums[i]));
ans.push(...temp);
// for (let j = 0; j < temp.length; j++) {
// temp[j].push(nums[i]);
// ans.push(temp[j]);
// }
}
}
}
return ans;
}
}
然后就可以快乐的搞了:
/**
* @param {number[]} nums
* @return {number[][]}
*/
const threeSum = function(nums) {
return nSum(nums, 0, 3);
};
/**
* @param {number[]} nums
* @param {number} target
* @return {number[][]}
*/
const fourSum = function(nums, target) {
return nSum(nums, target, 4);
};