给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
暴力
三次循环
先排序再找
以第一个数为基准,找后面的数,三个数为i,j,k,j从i+1开始,k从size-1开始,因为是拍过序的,所以和大于0,则k减一,反之亦然。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int size = int(nums.size());
int i(0), j(0), k(0);
vector<vector<int>> res;
sort(nums.begin(), nums.end());
vector<int> tmp(3, 0);
for(; i < size - 2; ++i)
{
if(nums[i] > 0) break;
if(i > 0 && nums[i] == nums[i - 1]) continue;
j = i + 1;
k = size - 1;
while(j < k)
{
int sum = nums[i] + nums[j] + nums[k];
if(sum > 0) k--;
else if(sum < 0) ++j;
else
{
res[0] = nums[i], res[1] = nums[j], res[2] = nums[k];
res.push_back(tmp);
while(j < k && nums[j] == nums[++j]);
}
}
}
return res;
}
}
执行用时 :80 ms, 在所有 C++ 提交中击败了92.41%的用户
内存消耗 :15.1 MB, 在所有 C++ 提交中击败了36.82%的用户
HashMap
全部丢到HashMap,然后两次循环,在HashMap里找加起来等于0的,但是需要排除一些情况
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
unordered_map<int, unordered_set<int>> m;
vector<vector<int>> res;
vector<int> tmp(3, 0);
int i(0), j(0);
int size(nums.size());
for (; i < size; ++i)
{
auto itFind = m.find(nums[i]);
if (itFind == m.end())
{
unordered_set<int> s;
s.insert(i);
m.insert(make_pair(nums[i], s));
}
else
itFind->second.insert(i);
}
for (i = 0; i < size - 1; ++i)
{
for (j = i + 1; j < size; ++j)
{
auto itFind = m.find(0 - nums[i] - nums[j]);
if (itFind != m.end())
{
auto itb(itFind->second.begin()), ite(itFind->second.end());
for (; itb != ite; ++itb)
{
if (*itb <= j) continue;
tmp[0] = nums[i], tmp[1] = nums[j], tmp[2] = nums[*itb];
sort(tmp.begin(), tmp.end());
if (find(res.begin(), res.end(), tmp) == res.end())
res.push_back(tmp);
}
}
}
}
return res;
}
};
//写着实在有点恶心了,发现这个方法并不是很好,因为找到结果后还要去重然后
//还要对装有一次结果的vector排序,313个用例过了307个,逻辑没问题,应该是
//find那消耗的时间比较多,超过时间限制了,可以考虑用一个set装一下结果,然后再find
//试了一下还是在最后超出时间限制,放弃了