题目描述
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
-
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]] -
示例 2:
输入:nums = []
输出:[] -
示例 3:
输入:nums = [0]
输出:[]
提示:
0 <= nums.length <= 3000
-105 <= nums[i] <= 105
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
三个数看似要做三重循环,但是实际上是可以优化成两层循环的,优化的前提是有序,因此第一步先把数组进行升序排序。
然后,先确定第一个数,第一个数的遍历范围为0~n-2;再确定后面两个数,其中的第一个数的遍历范围为1~n-1,第二个数的遍历范围为n~2(注意这个数是倒着遍历的),这两个数是同时遍历的,也可以说是双指针p和q,循环终止的条件是 p >= q。
- 若 nums[i] + nums[p] + nums[q] == 0,将i、p、q放入List<Integer>中,再放入List<List<Integer>>中。之后p指向下一个不一样的数字、q指向下一个不一样的数字(寻找不一样的数字需要用一个小循环)
- 若 nums[i] + nums[p] + nums[q] < 0,说明 p 指向的数字过小,p指向下一个不一样的数字
- 若 nums[i] + nums[p] + nums[q] > 0,说明 q 指向的数字过大,q指向下一个不一样的数字
对 i 的循环也遵循寻找下一个不一样的数字这一原则。
代码详解
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums); // 先排序
List<List