题目 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
1 2 输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]]
示例 2:
示例 3:
1 2 3 提示: 0 <= nums.length <= 3000 -105 <= nums[i] <= 105
思路 本题的难点在于去除重复的元素,这个题类似于全排列II、子集II都是需要排序后去重
第一种:三种for循环暴力求解
第二种:for循环的时间复杂度太高,在O(n^3^),优化后使用两次for循环,在第三次的时候我们使用两个指针来代替(因为我们已经使用了排序,所以才能使用指针)
先对数组进行排序
第一层为for循环,第二层为while循环(left < right)
要排除重复元素,如果这个值和前面的值相等,left++,如果和后面的值相等right————
如果这两个值的和相等,添加到元素,left++,right–
如果这两个数小于0 ,left++
大于0,right–
实现 暴力破解:提交超时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 private static class Solution { public List<List<Integer>> threeSum(int [] nums) { Arrays.sort(nums); if (nums[0 ] > 0 ){ return null ; } List<List<Integer>> res = new ArrayList<>(); int length = nums.length; for (int i = 0 ; i < length; i++) { if (i > 0 && nums[i - 1 ] == nums[i]) { continue ; } for (int j = i + 1 ; j < length; j++) { if (j > i + 1 && nums[j - 1 ] == nums[j]) { continue ; } for (int k = j + 1 ; k < length; k++) { if (k > j + 1 && nums[k - 1 ] == nums[k]) { continue ; } if (nums[i] + nums[j] + nums[k] == 0 ) { ArrayList<Integer> list = new ArrayList<>(); list.add(nums[i]); list.add(nums[j]); list.add(nums[k]); res.add(list); } } } } return res; } }
指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 private static class Solution2 { public List<List<Integer>> threeSum(int [] nums) { Arrays.sort(nums); List<List<Integer>> res = new ArrayList<>(); int length = nums.length; int left; int right; for (int i = 0 ; i < length; i++) { if (i > 0 && nums[i - 1 ] == nums[i]) { continue ; } left = i + 1 ; right = length - 1 ; while (left < right) { if (left > i + 1 && nums[left] == nums[left - 1 ]) { left++; continue ; } if (right < length - 1 && nums[right] == nums[right + 1 ]) { right--; continue ; } if (nums[i] + nums[left] + nums[right] == 0 ) { ArrayList<Integer> list = new ArrayList<>(); list.add(nums[i]); list.add(nums[left]); list.add(nums[right]); res.add(list); } if (nums[i] + nums[left] + nums[right] < 0 ) { left++; } else { right--; } } } return res; } }