哈希表 - 三数之和

15. 三数之和


方法一:排序+双指针

javascript 复制代码
/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var threeSum = function(nums) {
    const res = [], len = nums.length;
    // 将数组排序
    nums.sort((a, b) => a - b)
    for (let i = 0; i < len; i++) {
        let l = i + 1, r = len - 1, iNum = nums[i];
        // 将数组排过序,如果第一个数大于0直接返回res
        if (iNum > 0) return res
        // 去重
        if (iNum == nums[i - 1]) continue
        while (l < r) {
            let lNum = nums[l], rNum = nums[r], threeSum = iNum + lNum + rNum
            // 三数之和小于0,则左指针向右移动
            if (threeSum < 0) l++
            else if (threeSum > 0) r--
            else {
                res.push([iNum, lNum, rNum])
                // 去重
                while (l < r && nums[l] == nums[l + 1]) {
                    l++
                }
                while (l < r && nums[r] == nums[r - 1]) {
                    r--
                }
                l++
                r--
            }
        }
    }
    return res
};

方法二:递归

javascript 复制代码
/**
 *  nsum通用解法,支持2sum,3sum,4sum...等等
 *  时间复杂度分析:
 *  1. n = 2时,时间复杂度O(NlogN),排序所消耗的时间。、
 *  2. n > 2时,时间复杂度为O(N^n-1),即N的n-1次方,至少是2次方,此时可省略排序所消耗的时间。举例:3sum为O(n^2),4sum为O(n^3)
 * @param {number[]} nums
 * @return {number[][]}
 */
var threeSum = function (nums) {
    // nsum通用解法核心方法
    function nSumTarget(nums, n, start, target) {
        // 前提:nums要先排序好
        let res = [];
        if (n === 2) {
            res = twoSumTarget(nums, start, target);
        } else {
            for (let i = start; i < nums.length; i++) {
                // 递归求(n - 1)sum
                let subRes = nSumTarget(
                    nums,
                    n - 1,
                    i + 1,
                    target - nums[i]
                );
                for (let j = 0; j < subRes.length; j++) {
                    res.push([nums[i], ...subRes[j]]);
                }
                // 跳过相同元素
                while (nums[i] === nums[i + 1]) i++;
            }
        }
        return res;
    }

    function twoSumTarget(nums, start, target) {
        // 前提:nums要先排序好
        let res = [];
        let len = nums.length;
        let left = start;
        let right = len - 1;
        while (left < right) {
            let sum = nums[left] + nums[right];
            if (sum < target) {
                while (nums[left] === nums[left + 1]) left++;
                left++;
            } else if (sum > target) {
                while (nums[right] === nums[right - 1]) right--;
                right--;
            } else {
                // 相等
                res.push([nums[left], nums[right]]);
                // 跳过相同元素
                while (nums[left] === nums[left + 1]) left++;
                while (nums[right] === nums[right - 1]) right--;
                left++;
                right--;
            }
        }
        return res;
    }
    nums.sort((a, b) => a - b);
    // n = 3,此时求3sum之和
    return nSumTarget(nums, 3, 0, 0);
};
相关推荐
Fanxt_Ja5 小时前
【LeetCode】算法详解#15 ---环形链表II
数据结构·算法·leetcode·链表
今后1237 小时前
【数据结构】二叉树的概念
数据结构·二叉树
散11219 小时前
01数据结构-01背包问题
数据结构
消失的旧时光-194319 小时前
Kotlinx.serialization 使用讲解
android·数据结构·android jetpack
Gu_shiwww20 小时前
数据结构8——双向链表
c语言·数据结构·python·链表·小白初步
苏小瀚21 小时前
[数据结构] 排序
数据结构
睡不醒的kun1 天前
leetcode算法刷题的第三十四天
数据结构·c++·算法·leetcode·职场和发展·贪心算法·动态规划
吃着火锅x唱着歌1 天前
LeetCode 978.最长湍流子数组
数据结构·算法·leetcode
Whisper_long1 天前
【数据结构】深入理解堆:概念、应用与实现
数据结构
IAtlantiscsdn1 天前
Redis7底层数据结构解析
前端·数据结构·bootstrap