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:
- Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
- 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)
解题思路:
3Sum对初学者估计是丈二和尚摸不着头脑,其实NSum都有固定的解法。参考链接:
http://tech-wonderland.net/blog/summary-of-ksum-problems.html
基本上所有思路都是排序后查找,防止出现List的重复,因此想到使用set类型,JAVA实现如下:
static public List<List<Integer>> threeSum(int[] num) { LinkedHashSet<List<Integer>> set = new LinkedHashSet<List<Integer>>(); if (num.length <= 2) return new ArrayList<List<Integer>>(set); final int tar = 0; Arrays.sort(num); for (int i = 0; i < num.length - 2; i++) { int j = i + 1, k = num.length - 1; while (j < k) { if (num[i] + num[j] + num[k] < tar) j++; else if (num[i] + num[j] + num[k] > tar) k--; else { set.add(Arrays.asList(num[i], num[j], num[k])); j++; k--; } } } return new ArrayList<List<Integer>>(set); }
结果第一次提交Time Limit Exceeded,第二次提交竟然神奇般的通过了!!!时间425ms,估计也是擦线飘过。
原因在于set每添加一个元素都会和set中元素进行比较,也就是说需要一次遍历,这样每添加一个元素,时间开销就会比较大,因此修改代码如下,时间322 ms:
static public List<List<Integer>> threeSum(int[] num) { ArrayList<List<Integer>> list = new ArrayList<List<Integer>>(); final int tar = 0; Arrays.sort(num); for (int i = 0; i < num.length - 2; i++) { int j = i + 1, k = num.length - 1; while(i < k && num[i]==num[i+1]) i++; while (j < k) { if (num[i] + num[j] + num[k] < tar) j++; else if (num[i] + num[j] + num[k] > tar) k--; else { list.add(Arrays.asList(num[i], num[j], num[k])); j++; k--; while(j<k&&num[j]==num[j-1]) j++; while(k>j&&num[k]==num[k+1]) k--; } } } return list; }
C++:
1 class Solution { 2 public: 3 vector<vector<int>> threeSum(vector<int>& nums) { 4 vector<vector<int>> res; 5 if (nums.size() <= 2) 6 return res; 7 const int tar = 0; 8 sort(nums.begin(),nums.end()); 9 for (int i = 0; i < nums.size() - 2; i++) { 10 int j = i + 1, k = nums.size() - 1; 11 while (i < k && nums[i] == nums[i + 1]) 12 i++; 13 while (j < k) { 14 if (nums[i] + nums[j] + nums[k] < tar) 15 j++; 16 else if (nums[i] + nums[j] + nums[k] > tar) 17 k--; 18 else { 19 res.push_back({ nums[i], nums[j], nums[k]}); 20 j++; 21 k--; 22 while (j<k&&nums[j] == nums[j - 1]) 23 j++; 24 while (k>j&&nums[k] == nums[k + 1]) 25 k--; 26 } 27 } 28 } 29 return res; 30 } 31 };