💻 [LeetCode Hot100] 三数之和🔥双指针法,Java实现!图文详解,小白也能秒懂!
✏️本文对应题目链接:三数之和
📌 题目描述
给你一个包含 n
个整数的数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j != k
且 nums[i] + nums[j] + nums[k] = 0
。请返回所有满足条件且不重复的三元组。
示例:
输入: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
� 解题思路(图文分解)
❗ 核心难点
如何高效找到所有不重复的三元组?
排序+双指针法(黄金思路)✨
关键步骤:
- 排序数组:方便去重和双指针操作
- 固定一个数:遍历数组,固定
nums[i]
作为第一个数 - 双指针查找:在
nums[i]
后面的区间内,使用双指针left
和right
查找满足条件的两个数 - 去重处理:跳过重复的
nums[i]
、nums[left]
和nums[right]
动态过程图解:
排序后数组:[-4, -1, -1, 0, 1, 2]
- 固定nums[0]=-4 → 双指针区间[-1, 2]
- left=1, right=5 → -1+2=1 < 4 → left++
- left=2, right=5 → -1+2=1 < 4 → left++
- left=3, right=5 → 0+2= 2 < 4 → left++
- 固定nums[1]=-1 → 双指针区间[-1, 2]
- left=2, right=5 → -1+2=1 = 1 → 找到[-1, -1, 2] left++ right--
- left=3, right=4 → 0+1=-1 = 1 → 找到[-1, 0, 1]
🚀 代码实现
import java.util.*;
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums); // 排序
for (int i = 0; i < nums.length - 2; i++) {
// 跳过重复的nums[i]
if (i > 0 && nums[i] == nums[i - 1]) continue;
int left = i + 1, right = nums.length - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum == 0) {
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
// 跳过重复的nums[left]和nums[right]
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
} else if (sum < 0) {
left++;
} else {
right--;
}
}
}
return result;
}
}
💡 复杂度分析
- 时间复杂度:O(n²) → 排序O(nlogn) + 双指针遍历O(n²)
- 空间复杂度:O(1) → 忽略结果存储空间,仅使用常数空间
🌟 总结要点
✅ 排序核心作用:方便去重和双指针操作
✅ 双指针思想:将三数之和问题转化为两数之和
✅ 适用场景:多数之和、区间查找问题
🔥 下期预告:《接雨水》双指针法的经典应用!