2013.12.1 23:52
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)
Solution:
Given an array of n numbers, find out all triples (a, b, c) that adds up to 0, and a <= b <= c.
The first step is a sort() to make binary search possible.
With 2-dimensional enumeration of $a and $b, we perform binary search for $c.
To ensure that no duplicate triples is recorded, I use the format "$a_$b_$c" as a hash key. An STL map is used to store the results, in order to detect duplicates.
Time complexity is O(n * log(n) + n^2 * log(n) + nres * log(nres)) = O(n^2 * log(n)), where $n is the length of th array, $nres is the number of results found. Space complexity is O(nres).
Accepted code:
1 // 1CE, 1RE, 1WA, 1AC, foolish mistakes all over... 2 #include <algorithm> 3 #include <map> 4 #include <string> 5 using namespace std; 6 7 class Solution { 8 public: 9 vector<vector<int> > threeSum(vector<int> &num) { 10 // IMPORTANT: Please reset any member data you declared, as 11 // the same Solution instance will be reused for each test case. 12 int i, j, k; 13 for(i = 0; i < result.size(); ++i){ 14 result[i].clear(); 15 } 16 result.clear(); 17 mm.clear(); 18 19 if(num.size() <= 0){ 20 return result; 21 } 22 23 string str; 24 vector<int> vt; 25 26 // 1CE here, declaration of $n missing 27 int n; 28 29 sort(num.begin(), num.end()); 30 n = num.size(); 31 for(i = 0; i < n; ++i){ 32 for(j = i + 1; j < n; ++j){ 33 k = binary_search(num, j + 1, n - 1, -(num[i] + num[j])); 34 if(k > j && k < n){ 35 sprintf(buf, "%d_%d_%d", num[i], num[j], num[k]); 36 str = string(buf); 37 if(mm.find(str) == mm.end()){ 38 mm[str] = 1; 39 vt.clear(); 40 vt.push_back(num[i]); 41 vt.push_back(num[j]); 42 vt.push_back(num[k]); 43 result.push_back(vt); 44 } 45 } 46 } 47 } 48 49 // 1WA, forgot to return the result... 50 return result; 51 } 52 private: 53 vector<vector<int>> result; 54 map<string, int> mm; 55 char buf[100]; 56 57 int binary_search(vector<int> &num, int left, int right, int target) { 58 int lp, mp, rp; 59 60 if(left < 0 || left >= num.size() || right < 0 || right >= num.size()){ 61 return -1; 62 } 63 64 if(left > right){ 65 return -1; 66 } 67 68 // 1RE here, use of $lp, $rp without initialization 69 if(target < num[left] || target > num[right]){ 70 return -1; 71 } 72 73 lp = left; 74 rp = right; 75 while(lp <= rp){ 76 mp = (lp + rp) / 2; 77 if(target < num[mp]){ 78 rp = mp - 1; 79 }else if(target > num[mp]){ 80 lp = mp + 1; 81 }else{ 82 return mp; 83 } 84 } 85 86 return -1; 87 } 88 };