判断给定的两个数是否是亲和数_算法练习之三数之和等于零

d380debed68d09c560a3bcf963487037.png

题目

题目来源于leetcode:
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
答案中不可以包含重复的三元组
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[[-1, 0, 1],[-1, -1, 2]]

问题

什么情况下三个数相加才会等于零

三个数中肯定有正数和负数。

什么情况下三个数相加不可能为零

如果在一组数据中最小的两个数相加为正数,则这两个数和后面的数相加不可能等于零
如果在一组数据中最小的数为正数,则该数和其它数字相加不可能等于零

怎样判断会出现重复的值

如果在一组数据中有两个数相等,则会出现重复的值

解决思路

在上面的问题中,我们可以提取出几个关键字,如最小、正数、负数、相等;那么我们如何在一组数据中直观的看到这些关键词所对应的数字呢?其实可以轻易的想到,那就是从小到大排序,这样一来我们就很轻易的对负数和正数进行划分,相等的数据也会是相邻的状态,三个数相加等于零一定是负数【左边】的数据和正数【右边】的数据选择三个才能相加等于零。

代码思路

1、首先我们需要排序
2、循环我们的数据
3、如果最小的数大于0直接结束循环
4、如果相邻的数据相等则跳过循环,避免重复
5、如果三个数相加等于零则存储到相应的二维数组中

上面的简单思路有一点我们需要注意,就是这三个数该怎么找,我们说3个数必须是有正数和负
数,那么我们可以有一种办法每次找数相加时,第三个数是从正数中挑选最大的,如果结果仍然为正数,说明正数太大,应该选择一个小的,即排好序的数组倒数第二个数据,以此类推,相反,如果结果为负数,说明负数应该往右边继续寻找。因此我们可以定义两个指针,即下标,对应最左和最右的数据

代码实现

func threeSum(nums []int) [][]int {
    if len(nums) < 3 {
        return [][]int{}
    }
    // 排序
    sort.Ints(nums)
    fmt.Println(nums)
    // 创建一个二维数组
    ret := make([][]int, 0, 0)
    for i := 0; i < len(nums); i = i + 1 {
        if nums[i] > 0 {
            break
        }
        if i > 0 && nums[i] == nums[i-1] {
            continue
        }
        // 左右指针指向数组的两端
        l := i + 1
        r := len(nums) - 1
        for l < r {
            sum := nums[i] + nums[l] + nums[r]
            if sum == 0 {
                ret = append(ret, []int{nums[i], nums[l], nums[r]})
                for l < r && nums[l] == nums[l+1] {
                    fmt.Println(nums[l], "    ", nums[l+1])
                    l++
                }
                for l < r && nums[r] == nums[r-1] {
                    r--
                }
                l++
                r--

            } else if sum > 0 {
                r--
            } else if sum < 0 {
                l++
            }
        }
    }
    return ret
}
非常感谢您读完此文,欢迎点赞、评论、转发。想要获取更多内容可以微信搜索陌无崖关注我,每日准时知识分享。^_^

本文欢迎转载,转载请联系作者,谢谢!

  • 公众号【常更新】:陌无崖
  • GitHub:https://github.com/yuwe1
  • 博客地址【定期更新】:https://mowuya.cn/

253abe27896e7bf34d83b356fa6544c5.png
打开微信扫一扫
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值