问题:
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note: The solution set must not contain duplicate triplets.
For example, given array S = [-1, 0, 1, 2, -1, -4],A solution set is:[ [-1, 0, 1], [-1, -1, 2]]
解决:
① 首先想到暴力破解,O(n^3)的时间复杂度,必然超时。
② 数组排序+双指针 O(n^2) --- 动态规划
第一步,对数组排序。
第二步, 分析1:对于元素 S[i] , 最后的答案可以分为两种,包含 S[i] 的,和不包含 S[i] 的。当包含 S[i] 的情况都找到后,后续就可以不用再考虑 S[i] 。 分析2:对于 S[i] , l = i+1, r = len-1 。若 s[i] + S[l] + S[r] == 0, 则为原问题的一个解。 当 S[i] + S[l] > -S[r] 时,则 r-- 当 S[i] + S[l] < -S[r] 时,则 l++ 当 S[i] + S[i] = -S[r] 时, 表示是原问题的一个解,则 l++, r--; 第三步,性能优化。同样根据分析1,若 S[i] == S[i+1],可以跳过。class Solution { //72ms
List<List<Integer>> res = new ArrayList<>(); public List<List<Integer>> threeSum(int[] nums) { if(nums == null || nums.length < 3) return res; Arrays.sort(nums); int len = nums.length; for (int i = 0;i < len - 2 ;i ++ ) { if(i > 0 && nums[i] == nums[i - 1]) continue; twoSum(nums,i + 1,len - 1,nums[i]); } return res; } public void twoSum(int[] nums,int begin,int end,int sum1){ while(begin < end){ if(nums[begin] + nums[end] + sum1== 0){ List<Integer> tmp = new ArrayList<>(); tmp.add(sum1); tmp.add(nums[begin]); tmp.add(nums[end]); res.add(tmp); while(begin < end && nums[begin] == nums[begin + 1]) begin ++; while(begin < end && nums[end] == nums[end - 1]) end --; begin ++; end --; }else if(nums[begin] + nums[end] + sum1< 0){ begin ++; }else{ end --; } } } }② 这样写简单点
class Solution { //81ms
List<List<Integer>> res = new ArrayList<>(); public List<List<Integer>> threeSum(int[] nums) { if(nums == null || nums.length < 3) return res; Arrays.sort(nums); int len = nums.length; for (int i = 0;i < len - 2 ;i ++ ) { if(i > 0 && nums[i] == nums[i - 1]) continue; twoSum(nums,i + 1,len - 1,nums[i]); } return res; } public void twoSum(int[] nums,int begin,int end,int sum1){ while(begin < end){ if(nums[begin] + nums[end] + sum1== 0){ res.add(Arrays.asList(sum1,nums[begin],nums[end])); while(++ begin < end && nums[begin] == nums[begin - 1]); while(-- end > begin && nums[end] == nums[end + 1]); }else if(nums[begin] + nums[end] + sum1< 0){ begin ++; }else{ end --; } } } }