力扣 -- 15.三数之和

简介: 力扣 -- 15.三数之和


题目链接:15. 三数之和 - 力扣(LeetCode)


对于这么一个题目我们该如何入手呢?


很多人的第一感觉就是随机选择三个数就是写一个三层循环,然后按顺序随机选择三个数求和看是否等于0就行了,但是三层循环的方法在这道题里是行不通的,这里虽然没有写出时间复杂度的要求,但是O(N^3)是跑不过这道题的,这道题的时间复杂度要求是O(N^2)。


那么要在O(N^2)内写出这道题,那就最多只能写两层循环。


要通过两层循环选三个数,那么只能是一层循环选一个数,另一层循环同时选两个数。


具体思路:先把数组按升序的方式排好;外层循环按顺序先选定第一个数,如果这个数大于0,那么外循环就结束了,因为数组是升序的,当三个数中的第一个数都大于0,那么加上后面的数之后不可能等于0的;如果第一个数小于等于0,然后在内循环里面定义left和right下标,通过左右下标查找两个和为0的数,则这两个数和外循环选到的第一个数就组成了三元组,但是题目要求不能有重复的三元组,所以需要额外开一个set存储这些三元组。


下面是一个参考代码:时间复杂度为O(N^2),空间复杂度为O(N^2),思路非常的清晰,已配上非常详细的注释,相信大家都能看懂这个简单的代码的。


class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> vv;//存储返回的三元组
        if (nums.size() < 3)//数组元素不足三个就直接返回了
        {
            return vv;
        }
        sort(nums.begin(), nums.end());//对数组进行排序
        set<vector<int>> set;//对三元组进行排序和去重(set的性质)
        int i = 0;
        for (i = 0; i < nums.size() - 2; i++)//外循环选的是第一个数,所以最多选到倒数第三个数
        {
            //确定第一个数
            int tmp = nums[i];
            //如果tmp>0,数组升序,后面不可能找到<0的数,break;
            if (tmp > 0)
            {
                break;
            }
            //由于三元组内容是不重复的,所以在选择第一个数的时候数组中的重复元素可以跳过
            if (i > 0 && nums[i] == nums[i - 1])
            {
                continue;
            }
            //内循环找两个和为0的数
            int begin = i + 1;
            int end = nums.size() - 1;
            //begin和end大小不能交叉
            while (begin < end)
            {
                //i位置的数已经被第一个数选择了,同一个数不能同时选择两次,需跳过
                if (begin == i)
                {
                    begin++;
                    //begin==end,说明中间无元素可选了
                    //break
                    if (begin == end)
                    {
                        break;
                    }
                }
                //i位置的数已经被第一个数选择了,同一个数不能同时选择两次,需跳过
                if (end == i)
                {
                    end--;
                    //begin==end说明中间无元素可选了
                    //break
                    if (begin == end)
                    {
                        break;
                    }
                }
                //如果三个数相加<0,说明begin选小了(数组是升序的),begin++,end位置已经是最大的值
                //了,不能变
                if (tmp + nums[begin] + nums[end] < 0)
                {
                    begin++;
                }
                //如果三个数相加>0,说明end选大了,end--,begin位置已经是最小的值
                //了,不能变
                else if (tmp + nums[begin] + nums[end] > 0)
                {
                    end--;
                }
                //三数相加等于0,说明这是一个三元组,插入到insert中
                else
                {
                    //找到的begin位置的元素的下一个元素还可能和begin位置的值相同,
                    //这时可以去除重复的元素,减少运行的次数
                    while (begin + 1 < end && nums[begin] == nums[begin + 1])
                    {
                        begin++;
                    }
                    //找到的end位置的元素的上一个元素还可能和end位置的值相同,
                    //这时可以去除重复的元素,减少运行的次数
                    while (begin < end - 1 && nums[end] == nums[end - 1])
                    {
                        end--;
                    }
                    //用这三个数构成一个三元组vector,这时已经是按顺序排好了
                    //直接插入到set就行
                    vector<int> v = { tmp,nums[begin],nums[end] };
                    set.insert(v);
                    //改变坐标,继续寻找下一个三元组
                    begin++;
                    end--;
                }
            }
        }
        //最后把set里存的三元组插入到vv里返回即可
        for (auto& e : set)
        {
            vv.push_back(e);
        }
        return vv;
    }
};
相关文章
|
网络协议 网络架构 数据格式
网络初识:局域网广域网&网络通信基础
网络初识:局域网广域网&网络通信基础
921 5
|
数据采集 PyTorch 算法框架/工具
PyTorch基础之数据模块Dataset、DataLoader用法详解(附源码)
PyTorch基础之数据模块Dataset、DataLoader用法详解(附源码)
2264 0
|
25天前
|
数据采集 人工智能 搜索推荐
AI 问答占 52%!长沙别墅装修 GEO 突围:30 天引用率暴涨 40%
周有贵,巴黎学院人工智能博士,GGI商学院GEO首席技术专家,专注AI时代数字营销革新。2025年12月1日,长沙著名别墅设计师张主华专程拜访交流,共探GEO技术在装修设计行业中的AI引流逻辑与实操应用。面对生成式AI问答入口占比突破52%的新趋势,传统SEO正被GEO取代——从链接点击到答案呈现,企业需通过构建灯塔内容、E-E-A-T信任链与结构化数据,让品牌信息被AI优先引用。本次对话揭示:未来流量之争,本质是“被AI推荐”的能力之争。
|
4月前
|
机器学习/深度学习 算法 测试技术
NSA稀疏注意力深度解析:DeepSeek如何将Transformer复杂度从O(N²)降至线性,实现9倍训练加速
本文将深入分析NSA的架构设计,通过详细的示例、可视化展示和数学推导,构建对其工作机制的全面理解,从高层策略到底层硬件实现均有涉及。
422 0
NSA稀疏注意力深度解析:DeepSeek如何将Transformer复杂度从O(N²)降至线性,实现9倍训练加速
|
网络协议 网络安全 数据安全/隐私保护
windocs连接麒麟桌面---vnc软件
windocs连接麒麟桌面---vnc软件
665 0
|
8月前
|
前端开发 Java API
Spring MVC 数据绑定机制详解:@ModelAttribute vs. @RequestParam 和 @PathVariable
本文深入解析了Spring MVC的数据绑定机制,重点对比了`@RequestParam`、`@PathVariable`和`@ModelAttribute`三种注解的使用场景与功能。`@RequestParam`适用于从查询参数或表单数据中提取简单值;`@PathVariable`用于从URL路径中获取资源标识符;而`@ModelAttribute`则能将多个请求参数自动绑定到Java对象,支持复杂数据结构的处理。通过实际案例分析,帮助开发者根据需求选择合适的注解,提升API设计与表单处理效率。
659 9
|
机器学习/深度学习 算法
【机器学习】过拟合和欠拟合怎么判断,如何解决?(面试回答)
本文介绍了如何通过观察训练误差和验证误差来判断模型是否出现过拟合或欠拟合,并提供了相应的解决方案,包括增加数据、调整模型复杂度、使用正则化技术等。
1648 1
51单片机用汇编语言实现独立按键检测,每个按键有不同功能,包含按键消抖程序
51单片机用汇编语言实现独立按键检测,每个按键有不同功能,包含按键消抖程序
477 3
|
安全 Shell Linux
如何禁止某个用户使用ssh登录
本文介绍了五种禁止用户通过SSH登录的方法:1) 修改`/etc/ssh/sshd_config`文件中的`DenyUsers`和`DenyGroups`来阻止特定用户或用户组登录;2) 将用户的默认shell设置为`/usr/sbin/nologin`或`/bin/false`以禁用其SSH访问;3) 利用PAM(可插入认证模块)通过编辑`/etc/security/sshd.conf`来限制登录权限;4) 通过编辑`/etc/hosts.deny`文件拒绝特定用户的SSH访问;5) 锁定或禁用用户账号以阻止所有类型的登录。每种方法都提供了详细的步骤指导。
2081 1
|
算法 关系型数据库 MySQL
mysql忘记密码怎么办(附免密登录和修改密码)
mysql忘记密码怎么办(附免密登录和修改密码)
6681 0
mysql忘记密码怎么办(附免密登录和修改密码)

热门文章

最新文章