• 每天一道算法题(六)——返回一组数字中所有和为 0 且不重复的三元组



    前言

    注意:答案中不可以包含重复的三元组。


    1、问题

    给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。
    请你返回所有和为 0 且不重复的三元组。

    2、示例

    示例 1:
    输入:nums = [-1,0,1,2,-1,-4]
    输出:[[-1,-1,2],[-1,0,1]]
    解释:
    nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
    nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
    nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
    不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
    注意,输出的顺序和三元组的顺序并不重要。
    示例 2:
    输入:nums = [0,1,1]
    输出:[]
    解释:唯一可能的三元组和不为 0 。
    示例 3:
    输入:nums = [0,0,0]
    输出:[[0,0,0]]
    解释:唯一可能的三元组和为 0 。

    3、解决方法

    let nums = [-1,0,1,2,-1,-4];
    var threeSum = function(nums) {
        let newArray = []; // 1-1:定义一个空数组接收返回的数据
        let len = nums.length; // 1-2:获取传入输入数组的长度
        if(nums == null || len < 3) return newArray; // 2:如果数组为null或者数组的长度小于3 返回空数组
        nums.sort((a,b)=>a-b); // 3:将传入数组从小到大排序
        for(let x =0;x<len;x++){
            if(nums[x] > 0) break // 4:如果当前项大于0,三数之和不可能等于0,直接结束循环
            if (x > 0 && nums[x] == nums[x-1])continue; // 注意点:若x项和x的前一项相等,会导致返回数据重复了
            let y = x+1
            let z = len-1
            // 5-0循环判断第n+1项 是否小于 总长度-1(最后一项)
            while(y < z){
                 // 5-1-1:定义一个三数之和
                const sum = nums[x] + nums[y] + nums[z];
                // 5-1-2: 如果三数之和等于0,说明符合条件,添加到新数组中
                if(sum === 0){
                    newArray.push([nums[x], nums[y],nums[z]])
                    // 5-1-4注意点:由于数组本身不去重,导致y和z容易重复
                    // 若其中y及其下一项或z及其前一项相等则会导致返回数组重复
                    while (y<z && nums[y] == nums[y+1]){
                        y++;
                    }
                    while (y<z && nums[z] == nums[z-1]){
                        z--;
                    }
                    // 5-1-3:如果三数之和符合,那么找符合的当前下一项和最后一项的前一项
                    y++;
                    z--;
                } else if(sum < 0){
                    // 5-2:如果三数之和小于0,找排序后的下一项
                    y++
                } else if(sum > 0){
                    // 5-3:如果三数之和大于0,找排序后最大的前一项(如示例的排序后找完2后找1)
                    z--
                }
            }
        }
        console.log('res', newArray);
    };
    threeSum(nums);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    4、效果

    在这里插入图片描述

    5、注意点

    在这里插入图片描述

    如果你不加下面截图的代码,你的结果如上图所示

    在这里插入图片描述

  • 相关阅读:
    k8s快速查看pod对应的容器
    没有设计经验的新手如何制作一本电子画册?
    小H靶场学习笔记:DC-2
    golang 信道的讲解与应用--channel(五)
    Python测试框架 Pytest —— mock使用(pytest-mock)
    华为OD机考:0030-0031-n*n数组中二进制的最大数、整数的连续自然数之和
    面试必问 创建10个a点击弹出下标
    【死磕NIO】— 探索 SocketChannel 的核心原理
    JSP CMS 校园服务系统myeclipse定制开发mysql数据库网页模式java编程jdbc
    设计模式:享元模式 (我称之为网盘小视频模式/共享单车模式)
  • 原文地址:https://blog.csdn.net/weixin_44784401/article/details/134497067