1 题目要求:
Given an array nums
of n integers, are there elements a, b, c in nums
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.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
2 解决方法:
类比于sum two,很容易想到将第三个数的相反数作为两数之和,得到以下代码,但是最后一个测试的时间超时。
class TreeSumLess {
public:
bool operator()(const vector<int>&nums1, const vector<int>&nums2) {
int i = 0;
while ((i < 3) && (nums1[i] == nums2[i])) i++;
if (i == 3) return false;
else if (nums1[i] < nums2[i]) return true;
else return false;
}
};
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ret;
for (int i = 0; i < nums.size(); i++) {
unordered_map<int, int> hash;
for (int j = i+1; j < nums.size(); j++) {
int value = -nums[i] - nums[j];
unordered_map<int, int>::iterator it1 = hash.find(value);
if (it1 != hash.end()) {
vector<int> temp = {nums[i],nums[j],value};
sort(temp.begin(), temp.end(), less<int>());
ret.push_back(temp);
}
hash[nums[j]] = value;
}
}
sort(ret.begin(), ret.end(), TreeSumLess());
vector<vector<int>>::iterator pos = unique(ret.begin(), ret.end());
/*ret.resize(distance(ret.begin(), pos));*/
ret.erase(pos,ret.end());
return ret;
}
};
在特定情况下,例如全0,排序部分删重过程计算量很大,进一步改进的算法:
先对向量进行排序,中间可以根据排序特性减少重复的计算。
class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
vector<vector<int> > res;
sort(num.begin(), num.end());
for (int i = 0; i < num.size(); i++) {
int target = -num[i];
int front = i + 1;
int back = num.size() - 1;
while (front < back) {
int sum = num[front] + num[back];
// Finding answer which start from number num[i]
if (sum < target)
front++;
else if (sum > target)
back--;
else {
vector<int> triplet(3, 0);
triplet[0] = num[i];
triplet[1] = num[front];
triplet[2] = num[back];
res.push_back(triplet);
// Processing duplicates of Number 2
// Rolling the front pointer to the next different number forwards
while (front < back && num[front] == triplet[1]) front++;
// Processing duplicates of Number 3
// Rolling the back pointer to the next different number backwards
while (front < back && num[back] == triplet[2]) back--;
}
}
// Processing duplicates of Number 1
while (i + 1 < num.size() && num[i + 1] == num[i])
i++;
}
return res;
}
};
算法复杂度O(n2)
空间复杂度O(1)
3 总结
复习了哈希表、vector中sort erase、unique。排序预处理后的数据,在算法中会增加顺序的特性可以利用。: