力扣 leetcode 15. 三数之和

问题描述

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

提示:

  • 3 <= nums.length <= 3000
  • -10^5 <= nums[i] <= 10^5

示例

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

# 解题思路
此题一般用三个 `for` 循环即可解决,但是题目要求答案不能重复。因此,要么使用一个集合来保存已经记录过的答案,要么添加约束条件,使保存的答案不会重复。这里我们选择第二种方法,初始的 `nums` 是一个无序列表,我们可以对其进行排序,就可以保证答案中 `a <= b <= c` 成立。这样每次添加的解 `{a,b,c}` 也能保证有序。

然后,还可能存在如 `nums=[0,0,0,0]` 的情况,我们还需记录本次循环与上一次循环时的解是否一致,一致的话就不需要再搜索了。

既然需要对原数组进行排序,又需要保证不重复遍历,那我们可以考虑使用 `map` 来记录每个不同的元素。由于 `map` 是有序的,我们遍历时也能保证不会遍历到重复的结果。
``` C++
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        map<int, int> mp;
        for(int i = 0; i < nums.size(); i++){
            mp[nums[i]]++; //统计每个元素的出现次数
        }
        int tmp;
        for(auto i = mp.begin(); i != mp.end(); i++){
            if(i->first > 0){ // i->first <= j->first <= tmp,因此i->first <= 0
                break;
            }
            i->second--;
            for(auto j = i; j != mp.end(); j++){
                if(j->first + i->first > 0){ // 第三个数一定大于前两个数,因此前两个数的和一定要<=0
                    break;
                }
                if(j->second){
                    tmp = -(i->first + j->first);
                    if(tmp >= j->first){ 
                        if(tmp == j->first && j->second > 1){ // 判断第二,第三个数相等的情况
                            res.push_back({i->first, tmp, tmp});
                        }
                        else if(tmp > j->first && mp.count(tmp)){ // 第二,第三个数不等的情况
                            res.push_back({i->first, j->first, tmp});
                        }
                    }
                }
            }
        }
        return res;
    }
};
posted @ 2022-12-01 20:04  greatestchen  阅读(18)  评论(0编辑  收藏  举报