class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ans{};
unordered_map<int, int> countPerNum{};
unordered_set<int> keys{};
for(int x : nums)
{
++countPerNum[x];
keys.insert(x);
}
// If there are more than one zero, then say there is only one zero.
if (countPerNum.contains(0))
{
// If there are three zeros, then add triplet to answer.
if (countPerNum[0] > 2)
{
ans.push_back({0, 0, 0});
}
countPerNum[0] = 1;
}
// If there are duplicate numbers and there exists their corresponding triplet_number, then add triplet to answer.
for(auto const& [num, count] : countPerNum)
{
if ( (count > 1) && (countPerNum.contains(-(2*num))) )
{
ans.push_back({num, num, -(2*num)});
}
}
// The number a and number b will be different.
for(int a : keys)
{
countPerNum.erase(a);
unordered_set<int> seen{};
for(auto const& [b, count] : countPerNum)
{
seen.insert(b);
int diff = 0 - a - b;
// !seen.contains(diff) takes care of two cases.
// Do not count triplets that contain two b's. They have already been counted above.
// The triplet containing a + b has already been added. If diff equals b, do not add it again.
if (countPerNum.contains(diff) && !seen.contains(diff))
{
ans.push_back({a, b, diff});
}
}
}
return ans;
}
};