4Sum

Q:
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)
排 版真的是比较弱,其实是可以通过非递归的方式写出这个代码的,时间大概是n^2再加上一个stl排序的时间,但是下面的方式会比较通用于nSum的情况。 4Sum也可以轻松搞过,需要注意的是因为不允许有重复的结果出现,所以如果先选定了一个元素做头,下次不要再选这个元素。

A:

class Solution {
 public:
  vector<vector<int> > threeSum(vector<int> &num) {
    // Start typing your C/C++ solution below
// DO NOT write int main() function
sort(num.begin(), num.end());
    return nSum(num, 0, 3, 0);
  }
 private:
  vector<vector<int> >  nSum(const vector<int> &num, int sum, int n, int pos) {
    int len = num.size();
vector<vector<int> > results;
if (n < 2 || len - pos < n) {
 return results;
}
vector<vector<int> > part_results;
if (n == 2) {
   return twoSum(num, sum, pos);
}
for (int i = pos; i <= len - n; ++i) {
 while (i > pos && i < len && num[i] == num[i - 1]) ++i;
 if (i > len - n) return results;
 part_results = nSum(num, sum - num[i], n - 1, i + 1);
 if (part_results.empty()) {
continue;
 }
 for (int j = 0; j < part_results.size(); ++j) {
   vector<int> son_result;
son_result.push_back(num[i]);
son_result.insert(son_result.end(), part_results[j].begin(), part_results[j].end());
results.push_back(son_result);
 }
    }
return results;
  }
  
  vector<vector<int> >  twoSum(const vector<int> &num, int sum, int pos) {
     vector<vector<int> > results;
     int len = num.size();
     if (len - pos < 2) {
       return results;
     }
     int begin = pos;
     int end = num.size() - 1;
     while (begin < end) {
      while (begin > pos && begin < len && num[begin] == num[begin - 1]) ++begin;
      if (begin > len - 2 || begin >= end) return results;
      if (num[begin] + num[end] == sum) {
        vector<int> son_result;
        son_result.push_back(num[begin]);
        son_result.push_back(num[end]);
        results.push_back(son_result);
        while (begin + 1 < end && num[begin] == num[begin + 1]) ++begin;
        while (end - 1 >= 0 && num[end] == num[end - 1]) --end;
        ++begin;
        --end;
      } else if (num[begin] + num[end] > sum) {
        --end;
      } else {
        ++begin;
      }
    }
    return results;
  }
};

 

posted @ 2013-06-13 15:05  dmthinker  阅读(183)  评论(0)    收藏  举报