15. 三数之和 - 力扣(LeetCode)
给你一个整数数组 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
1.解法
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> ret = new LinkedList<>();
List<Integer> feasibleSolution ;
for (int i = 0; i < nums.length -2; i++) {
// 确保首位数每次参与循环计算的都不一样
if (i == 0 || nums[i] != nums[i-1]) {
int k = nums.length - 1;
// 确保次位数每次参与循环计算的都不一样
for (int j = i+1; j < nums.length -1 ; j++) {
if(j == i+1 || nums[j] != nums[j-1]) {
// 在i 固定的时候,如何 i,j,k 之和偏大,变小的只有k
while (k > j && nums[k] + nums[i] + nums[j] > 0) {
k --;
}
// 突破循环之后,i,j,k 之后至少是不大于0
if (k > j && nums[k] + nums[i] + nums[j] == 0) {
feasibleSolution = new LinkedList<>();
feasibleSolution.add(nums[i]);
feasibleSolution.add(nums[j]);
feasibleSolution.add(nums[k]);
ret.add(feasibleSolution);
}
// 如果 if 没有执行,意味着 i,j k 之和 < 0,因此需要执行j++
}
}
}
}
return ret;
}
}