哈希表 - 三数之和

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);
};
相关推荐
ysu_03145 分钟前
leetcode数据结构与算法1~4
c语言·数据结构·学习·算法·leetcode
小欣加油7 分钟前
leetcode2574 左右元素和的差值
数据结构·c++·算法·leetcode·职场和发展
weixin_4617694026 分钟前
通过数组和队列构造二叉树方法(用于算法测试),C++ vector不能直接使用null
数据结构·c++·算法·vector·nullptr·null
千寻girling37 分钟前
一周没跑步了 ,今日跑步 5KM , 哑铃+健身 20min , 俯卧撑 30 个 ;
数据结构·c++·python·算法·leetcode·职场和发展·线性回归
专注API从业者40 分钟前
电商选品效率翻倍!基于 Open Claw + 淘宝商品 API 实现自动化监控选品(附完整可运行代码)
大数据·运维·数据结构·数据库·自动化
超梦dasgg1 小时前
Redis ZSet(有序集合)底层数据结构
数据结构·数据库·redis
南境十里·墨染春水3 小时前
数据结构 --- 红黑树
数据结构
Zhang~Ling5 小时前
C++ 红黑树封装:myset和mymap的底层实现
开发语言·数据结构·c++·算法
啦啦啦啦啦zzzz5 小时前
数据结构:堆排序
数据结构·c++·
San813_LDD6 小时前
[量化]《虚函数调用时间复杂度完全解析:为什么是 O(1) 以及它的真实代价》
java·数据结构·算法