【C++LeetCode】【热题100】三数之和【中等】-不同效率的题解【6】

题目:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
暴力方法:
在这里插入图片描述

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        std::unordered_set<std::string> uniqueValues;//保证结果唯一
        for(int i=0;i<nums.size();i++){//三个值暴力求解
            for(int j=0;j<nums.size();j++){
                for(int k=0;k<nums.size();k++){
                    if(i!=j && i!=k && j!=k && nums[i]+nums[j]+nums[k]==0){
                        vector<int> temp;
                        temp.push_back(nums[i]);
                        temp.push_back(nums[j]);
                        temp.push_back(nums[k]);
                        sort(temp.begin(),temp.end());//排序
                        ostringstream oss;
                        oss<<temp[0]<<temp[1]<<temp[2];
                        std::string temposs=oss.str();
                        //cout<<oss.str()<<endl;
                        
                        // for(const auto & elem:uniqueValues){
                        //     cout<<"---"<<elem<<endl;
                        // }
                        if(uniqueValues.find(temposs)!=uniqueValues.end()){//结果去重
                            
                            //cout<<temposs<<endl;
                        }
                        else{
                            uniqueValues.insert(temposs);
                            res.push_back(temp);
                        }

                    }
                }
            }
        }
        return res;
    }
};

优化方法1:

在这里插入图片描述

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        std::unordered_set<std::string> uniqueValues;//保证结果唯一
        std::unordered_map<std::string,vector<int>>uniqueKVs;

        for(int i=0;i<nums.size();i++){//优化下,选择二个
            for(int j=i+1;j<nums.size();j++){
                    vector<int> temp;
                    temp.push_back(nums[i]);
                    temp.push_back(nums[j]);
                    temp.push_back(0-(nums[i]+nums[j]));
                    sort(temp.begin(),temp.end());//排序
                    ostringstream oss;
                    oss<<i<<","<<j;
                    uniqueKVs[oss.str()]=temp;
                }
            }
        for(const auto & elem :uniqueKVs){//查找符合条件的
            std::string k=elem.first;
            size_t pos=k.find(",");
            int i=std::stoi(k.substr(0,pos));
            int j=std::stoi(k.substr(pos+1,k.size()-pos-1));        
            vector<int> temp=elem.second;
            for(int k=0;k<nums.size();k++){
                    if(i!=j && i!=k && j!=k && nums[i]+nums[j]+nums[k]==0){
                        ostringstream oss;
                        oss<<temp[0]<<temp[1]<<temp[2];
                        std::string temposs=oss.str();
                        cout<<oss.str()<<endl;
                        if(uniqueValues.find(temposs)!=uniqueValues.end()){//结果去重
                            //cout<<temposs<<endl;
                        }
                        else{
                            uniqueValues.insert(temposs);
                            res.push_back(temp);
                        }

                    }
                }
        }
        return res;
    }
};

优化方法2:

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(),nums.end());//排序 方便 去重 和查找
        for(int i=0;i<nums.size();i++){//优化下,选择二个
            if(i==0 || nums[i] != nums[i-1]){//去除 越界 和重复的值
            int k=nums.size()-1;//双指针 左右 逼近  使得并行查找
                for(int j=i+1;j<nums.size();j++){
                    if(j==i+1 || nums[j]!=nums[j-1]){//去除 越界 和重复的值
                        while(j<k && nums[i]+nums[j]+nums[k]>0){
                            k--;//并行查找合适的 k对应的值
                        }
                        if(j==k){
                            break;// 左边和右边 通过双指针都 查找了,不能再存在符合条件的了
                        }
                        if(nums[i]+nums[j]+nums[k]==0){
                            //获得符合条件的
                            res.push_back({nums[i],nums[j],nums[k]});
                        }
                    }
                }
            }
            }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fighting的码农(zg)-GPT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值