Leetcode:三数之和

news2024/11/25 21:20:38

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

普通版本(排序 + 双指针法)

分析:

1、我们可以通过三个循环嵌套找到符合题目要求的三元组组合

2、但由于题目要求中的三元组i、j、k并不要求连续,所以会出现下面的情况:

3、因此直接对原数组进行查找,可能会出现重复的情况,比如有abc的组合均满足条件但该组合有多种表现形式(a,c,b)(b,c,a)等重复的组合会导致我们的查找效率大大下降,因此我们应该先将数组进行排序,使得查找时三元组的顺序必然是从到大排序的,从而减少查找次数增加查找效率(假设排序前abc的组合满足要求,且a<=b<=c,那么排序后再进行查找时就不会出现(b,c,a)这种组合,最小的a一定是在最左边的)

sort(nums.begin(), nums.end());//排序

4、但是这样还不够,在循环时,相邻两次查找到的数组也不能相同否则也是重复,我们要跳转至下一个元素处,应该去查找组合(0,1,3):

//实现上述防止重复查找的逻辑伪代码:
nums.sort()
for(first = 0 .. n-1)
{
    // 只有和上一次枚举的元素不相同,我们才会进行枚举
    if (first == 0 or nums[first] != nums[first-1])
    {
        for(second = first+1 .. n-1)
        {
             if (second == first+1 or nums[second] != nums[second-1])
             {
                 for(third = second+1 .. n-1)
                {
                    if(third == second+1 or nums[third] != nums[third-1])
                    {
                        // 判断是否有 a+b+c==0
                        check(first, second, third)
                    }
                }
            }
        }
    }
}                   

5、此时每次查找时一定满足,a<a‘、b<b'、c<c’(带'的都是新一次查找的),但最坏时间复杂度仍为O(N^3),我们尝试继续优化,我们会发现如果我们固定了前两重循环枚举到的元素 a 和 b,那么只有唯一的 c 满足 a+b+c=0,当第二重循环往后查找一个元素 b′时,由于 b′>b ,那么满足 a+b′+c′=0的 c′ 一定有 c′<c 即 c′ 在数组中一定出现在 c 的左侧。也就是说,我们可以从小到大枚举 b,同时从大到小枚举 c,即第二重循环和第三重循环实际上是并列的关系。有了这样的发现,我们就可以保持第二重循环不变,而将第三重循环变成一个从数组最右端开始向左移动的指针,从而得到下面的伪代码:

nums.sort()//排序
for (first = 0 .. n-1)    
{
    if(first == 0 or nums[first] != nums[first-1])
    {
        third = n-1;// 第三重循环对应的指针
        for(second = first+1 .. n-1)
        {
            if(second == first+1 or nums[second] != nums[second-1])
            {
                // 向左移动指针,直到 a+b+c 不大于 0
                while(nums[first]+nums[second]+nums[third] > 0)
                {
                    third = third-1;
                }
                 // 判断是否有 a+b+c==0
                check(first, second, third)
            }    
        }
    }
}
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int n = nums.size();
        sort(nums.begin(), nums.end());//排序
        vector<vector<int>> ans;
        // 枚举 a
        for (int first = 0; first < n; ++first) 
        {
            // 需要和上一次枚举的数不相同
            if (first > 0 && nums[first] == nums[first - 1]) //first>0保证第一次循环可以正常进行,但是当第二次循环时如果两个a相同就,++first寻找下一个不相同的a
            {
                continue;
            }
            // c 对应的指针初始指向数组的最右端
            int third = n - 1;
            //int target = -nums[first];//获取a的负值,a+b+c = 0 => b + c = (-a)
            // 枚举 b
            for (int second = first + 1; second < n; ++second) 
            {
                // 需要和上一次枚举的数不相同
                if (second > first + 1 && nums[second] == nums[second - 1])//跟前面一样,首先第一次循环要可以正常进行
                {
                    continue;
                }
                // 需要保证 b 的指针在 c 的指针的左侧
                while(second < third && nums[first]+nums[second]+nums[third] > 0)
                {
                    --third;
                }
                // 如果指针重合,随着 b 后续的增加,就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
                if (second == third) 
                {
                    break;
                }
                if (nums[first]+nums[second]+nums[third] == 0) 
                {
                    ans.push_back({nums[first], nums[second], nums[third]});
                }
            }
        }
        return ans;
    }
};

时间复杂度:O(N^2)

空间复杂度:O(logN)(忽略存储答案的空间,额外的排序的空间复杂度为 O(log⁡N))

~over~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1805861.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大模型的发展历程

1、早期模型的探索与局限性 1.1早期模型的探索与局限性 从早期的符号逻辑到现代的深度学习 1 模型&#xff0c;AI 领域经历了数十年的探索和迭代&#xff0c;为后续突破打下了坚实基础。随着大数据的发展和 AI 计算能力的爆炸式增长&#xff0c;深度学习模型的崛起显得尤为突出…

Spring运维之业务层测试数据回滚以及设置测试的随机用例

业务层测试数据回滚 我们之前在写dao层 测试的时候 如果执行到这边的代码 会在数据库 里面留下数据 运行一次留一次数据 开发有开发数据库&#xff0c;运行有运行数据库 我们先连数据库 在pom文件里引入mysql的驱动和mybatis-plus的依赖 在数据层写接口 用mybatis-plus进…

使用Python在Word中创建和提取表格

目录 安装Python Word库 使用Python在Word中创建预定义行和列的表格 使用Python在Word中动态创建表格 使用Python在Word中提取表格数据 Word 文档中的表格是一种强大且灵活的数据组织和展示工具&#xff0c;它能将信息以行和列的形式有序地排列&#xff0c;使文档内容更加清…

SQL Developer迁移第三方数据库单表到Oracle

在SQL Developer中&#xff0c;除可用Migration Wizard迁移第三方数据库到Oracle外&#xff0c;单表的迁移可以用Copy To Oracle ...菜单。右键单击源表即可。 本例的源表为MySQL数据库employees中的表&#xff1a;departments。 Options页面&#xff1a;指定目标库&#xff…

如何将 Windows图片查看器的背景颜色改成浅色(灰白色)?

现在大家基本都在使用Win10系统&#xff0c;我们在双击查看图片时&#xff0c;系统默认使用系统自带的图片&#xff08;照片&#xff09;查看器去打开图片。图片查看器的背景色默认是黑色的&#xff0c;如下所示&#xff1a;&#xff08;因为大家可能会遇到同样的问题&#xff…

pxe自动装机与无人值守

一、pxe与无人值守 pxe&#xff1a;c/s 模式&#xff0c;允许客户端通过网络从远程服务器&#xff08;服务端&#xff09;下载引导镜像&#xff0c;加载安装文件&#xff0c;实现自动化安装操作系统。 pxe的优点&#xff1a; 1、规模化 同时装配多台服务器&#xff08;20多&…

Hive知识体系保姆级教程

一. Hive概览 1.1 hive的简介 Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张数据库表&#xff0c;并提供类SQL查询功能。 其本质是将SQL转换为MapReduce/Spark的任务进行运算&#xff0c;底层由HDFS来提供数据的存储&#xff0c;说白了h…

【wiki知识库】06.文档管理页面的添加--前端Vue部分

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 一、&#x1f525;今日目标 二、&#x1f43b;前端Vue模块的改造 BUG修改 1.wangeditor无法展示问题 2.弹窗无法正常关闭问题 2.1 添加admin-doc.vue 2.1.1 点击admin-ebook中的路由跳转到admin-doc 2.2.2 进入…

【DrissionPage】Linux上如何将https改为http

最近有个老板找我做一个自动化的程序&#xff0c;要求部署到Linux上 这是一个http协议的网站&#xff0c;chrome在默认设置下&#xff0c;会将http的网站识别成不安全的内容&#xff0c;然后自动将http转化成https访问 但是&#xff0c;这个http的网站它的加载项里既有http的…

Java | Leetcode Java题解之第132题分割回文串II

题目&#xff1a; 题解&#xff1a; class Solution {public int minCut(String s) {int n s.length();boolean[][] g new boolean[n][n];for (int i 0; i < n; i) {Arrays.fill(g[i], true);}for (int i n - 1; i > 0; --i) {for (int j i 1; j < n; j) {g[i]…

Centos X系统yum安装mysql数据库

安装之前需要将系统自带的mariadb-libs软件包删除。 检查是否存在mariadb-libs包。 yum list installed|grep mariadb-libs 删除mariadb-libs包 yum -y remove mariadb-libs 声明&#xff1a; 系统&#xff1a;CentOS-7-x86_64-DVD-2009 安装为最小化安装&#xff0c;没…

[线程与网络] Java虚拟机常考面试题(线程与网络完结)

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;线程与…

MySQL: 表的增删改查(基础)

文章目录 1. 注释2. 新增(Create)3. 查询(Retrieve)3.1 全列查询3.2 指定列查询3.3 查询字段为表达式3.4 别名3.5 去重: distinct3.6 排序: order by3.7条件查询3.8 分页查询 4. 修改 (update)5. 删除(delete)6. 内容重点总结 1. 注释 注释&#xff1a;在SQL中可以使用“–空格…

【React】Redux与React - 环境准备

配套工具 在React中使用redux&#xff0c;官方要求安装俩个其他插件 - Redux Toolkit 和 react-redux 配置基础环境 使用 CRA 快速创建 React 项目 npx create-react-app react-redux安装配套工具 npm i reduxjs/toolkit react-redux启动项目 npm run start

python中while循环实现九九乘法表

i 1while i < 9: # 控制行的循环j 1while j < i: # 控制每行的输出print(f"{j}*{i}{j * i}\t", end"")j 1print()i 1运行截图&#xff1a;

图解 Python 编程(12) | 文件和编码方式

&#x1f31e;欢迎来到Python 的世界 &#x1f308;博客主页&#xff1a;卿云阁 &#x1f48c;欢迎关注&#x1f389;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f31f;本文由卿云阁原创&#xff01; &#x1f4c6;首发时间&#xff1a;&#x1f339;2024年6月9日&am…

《编译原理》期末考试复习手写笔记(二)+真题(第四、五、六章)+课后习题答案

第四章考试题型【自顶向下语法分析】 考点梳理&#xff1a; 1.语法分析程序的设计 2.确定的自顶向下分析思想2.1 FIRST集合 2.2 FOLLOW集合 2. 3 SELECT集合 2. 4 LL(1)文法 3.LL(1)文法的判别 如何消除左公因子? 如何消除左递归? 4.非LL(1)到LL(1)文法的等价变换 5.LL(1)分…

Web后端开发(请求-简单参数)(一)

原始方式&#xff1a; 在原始的web程序中&#xff0c;获取请求参数&#xff0c;需要通过HttpServletRequest 对象手动获取。 RequestMapping("/simpleParam") public String simpleParam(HttpServletRequest request){//获取请求参数String name request.getParame…

物资材料管理系统建设方案(Word)—实际项目方案

二、 项目概述 2.1 项目背景 2.2 现状分析 2.2.1 业务现状 2.2.2 系统现状 三、 总体需求 3.1 系统范围 3.2 系统功能 3.3 用户分析 3.4 假设与依赖关系 四、 功能需求 4.4.11.7 非功能性需求 五、 非功能性需求 5.1 用户界面需求 5.2 软硬件环境需求 5.3 产品质量需求 5.4 接口…

springAOP 使用aop代替SqlsessionUtil业务层操作

在Maven框架pom配置文件中导入spring相关依赖&#xff1a; <dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><dependency…