三数之和

*给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

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

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

function threeSum($nums) {
        // 结果数组
        $res = [];

        // 数组为空或长度小于 3,返回空数组
        if (!$nums || ($len = count($nums)) < 3) {
            return $res;
        }

        // 对数组进行排序
        sort($nums);

        // 遍历数组
        foreach ($nums as $k => $v) {
            // 定义左右指针
            $l = $k + 1;
            $r = $len - 1;

            // 数组是经过排序的,当前值大于 0,
            // 说明后面相加后肯定是大于 0 的
            if ($v > 0) {
                break;
            }

            // 如果当前值和前一个值相同,
            // 则跳过当前循环,防止重复
            if ($k > 0 && $v === $nums[$k - 1]) {
                continue;
            }

            while ($l < $r) {
                $sum = $v + $nums[$l] + $nums[$r];

                // 对求和结果进行判断
                if ($sum === 0) {
                    // 和为 0,给结果数组添加元素
                    array_push($res, [$v, $nums[$l], $nums[$r]]);

                    // 去重操作
                    while ($nums[$l] === $nums[$l+1]){
                    	$l++;
                    }
                    while ($nums[$r] === $nums[$r-1]){
                    	$r--;
                    }

                    $l++;
                    $r--;
                } elseif ($sum < 0) {
                    // 和小于 0,左指针 + 1
                    $l++;
                } else {
                    // 和大于 0,右指针 - 1
                    $r--;
                }
            }
        }
        
        return $res;
    }

两数之和

    function twoSumHash($nums, $target)
    {
    	$hash = [];
        $n = count($nums);
        for ($i = 0; $i < $n; ++$i) {
            $diff = $target - $nums[$i];
            if (isset($hash[$diff])) return [$i, $hash[$diff]];
            $hash[$nums[$i]] = $i;
        }
        return [];
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值