给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请
你返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 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] 。 注意,输出的顺序和三元组的顺序并不重要。
public function threeNum($nums){
// [-1, 0, 1, 2, -1, -4];
sort($nums); // 给数组排序
$len = count($nums);
$result = [];
for ($i=0; $i<$len-2; $i++){
if ($i == 0 || $nums[$i] != $nums[$i-1]) {
$left = $i + 1;
$right = $len - 1;
while ($left < $right) {
$sum = $nums[$i] + $nums[$left] + $nums[$right];
if ($sum < 0) {
// 移动left 增加和的值
$left++;
} elseif ($sum > 0) {
$right--;
} else {
$result[] = [$nums[$left], $nums[$i], $nums[$right]];
while ($left < $right && $nums[$left] == $nums[$left + 1]) {
$left++;
}
while ($left < $right && $nums[$right] == $nums[$right - 1]) {
$right--;
}
$left++;
$right--;
}
}
}
}
return $result;
}
这个算法的逻辑是通过对数组排序,然后使用双指针来查找和为零的三元组
1 对输入的整数数组进行排序
2 遍历排序后的数组,然后对每个元素$Num[$i],使用双指针left 和 right 来查找符合条件的三元组。
3 在内部循环中,初始化 $left = $i+1,表示第二个元素,初始化$right = $len-1 表示最后一个元素;当$left<$right 的时候,检查当前三元组是否等于0 ,如果登录0存入结果集中。
4 如果和小于0移动left指针,增加和的值,如果大于0移动right 减少和的值。
5 继续遍历数组,直到找到所有的和等于0三元组为止