栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

力扣15:三数之和

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

力扣15:三数之和

力扣15:三数之和 题目描述

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

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

输入输出
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
输入:nums = []
输出:[]
输入:nums = [0]
输出:[]
解法一,暴力解法建立哈希去重

暴力解法的思路是采用两个for循环,先固定两个值,再用find函数去寻找是否有下一个。然后对查找结果进行排序,并且放入hash表中用来去重。但时间复杂度虽然是 O ( n 2 ) O(n^2) O(n2)但由于find函数也会有大量运算,所以递交leetcode的时候会产生运行超时

    //暴力解法
    vector>threeSum(vector&nums)
    {
        vector>numList;
        vectortemplist;
        map,int>hashList;
        //双重for循环然后找到匹配的值然后进行排序
        for(int i=0;i
            for(int j=i+1;j
                int temp=0-nums[i]-nums[j];

                auto res=find(nums.begin()+j+1,nums.end(),temp);

                if(res!=nums.end())
                {
                    templist.clear();
                    templist.push_back(nums[i]);
                    templist.push_back(nums[j]);
                    templist.push_back(temp);
                    sort(templist.begin(),templist.end());
                    hashList.insert(make_pair(templist,i));
                }
            }
        }
    auto index=hashList.begin();
    for(auto i:hashList)
    {
        numList.push_back(i.first);
    }
        return numList;
    }
方法2,使用双指针和排序

本题的主流思路是使用双指针方法,判断输入无序,输出有序的情况。首先第一点就是进行先对输入的数组进行排序。再接下来固定第一个字符。剩下的问题便变成了两数之和问题,可参考Leetcode第一题中的描述。本题我们采用双指针的方法,当两数之和大于目标值时,右指针左移,当两数之和小于目标值时,左指针右移。时间复杂度也为 O ( n 2 ) O(n^2) O(n2)

 vector>threeSum2(vector&nums)
    {
        vector>numList;
        int length=nums.size();
        //当输入的字符数量小于3的时候,直接跳出
        if(length<3)
        {
            return numList;
        }
        //对容器进行排序
        sort(nums.begin(),nums.end());
        //固定第一个数,进而转化成求两数之和的问题
        for(int i=0;i
            //当排序后第一个数值的值大于0,肯定接下来都大于0
            if(nums[0]>0)
            {
                return numList;
            }   

            //去重:若当前数被选择过,则跳过
            //continue作用,如果满足if里面的条件,则不执行循环语句中的剩余内容,跳出循环,执行下一次循环
            if(i>0&&nums[i]==nums[i-1])
                continue;
            
            //使用双指针方法
            int left=i+1;
            int right=length-1;
            int tempNum=-nums[i];

            while(left
                //两数之和太小,左指针右移
                if(nums[left]+nums[right]
                    left++;
                }
                //两数之和太大,右指针左移
                else if(nums[left]+nums[right]>tempNum)
                {
                    right--;
                }
                //当找到一个和为零的三元组,添加到结果中,并移动左右指针收缩,继续寻找
                else
                {
                    numList.push_back(vector{nums[i],nums[left],nums[right]});
                    left++;
                    right--;

                    //去重
                    while(left
                        left++;
                    }
                    while(left
                        right--;
                    }
                }
            }
        }
        

        return numList;
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/920559.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号