Files
LeetCode/双指针/3. 三数之和.md
T
2025-09-28 22:49:55 +08:00

94 lines
2.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 三数之和
## 题目
给你一个整数数组 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] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
提示:
3 <= nums.length <= 3000
-105 <= nums[i] <= 105
## 思路
- 预处理
- 排序
- 三个指针
- p, l, r
- p: Traverse Full
- l: p+1 ->
- r: <-nums.length-1
- 降级为两数之和
## 代码
```java
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
// Pre
Arrays.sort(nums);
// Init
int p, l, r;
List<List<Integer>> ans = new ArrayList<>();
// Traverse 1
for (p = 0; p < nums.length - 2; p++) {
// DISTINCT
if (p > 0 && nums[p - 1] == nums[p]) {
continue;
}
int target = -nums[p];
// Pointer
l = p + 1;
r = nums.length - 1;
// Traverse 2: Two Sum
while (l < r) {
int sum = nums[l] + nums[r];
if (sum < target) l++;
else if (sum > target) r--;
else {
ans.add(Arrays.asList(nums[p],nums[r],nums[l]));
// DISTINCT
while (l < r && nums[l] == nums[l + 1]) {
l++;
}
while (l < r && nums[r] == nums[r - 1]) {
r--;
}
l++;
r--;
}
}
}
return ans;
}
}
```