【数组】【双指针】三数之和

news2024/11/30 12:49:38

打算冲一把算法类比赛,之前一直对算法提不起兴趣,也有我自己对它的抵触,本身算法也比较菜。
但现在打算勤勤恳恳刷题,踏踏实实总结,冲!

数组——双指针

三数之和

在这里插入图片描述
该题力扣网址

错误做法

三重循环框架,最浅显的思路,复杂度是N^3,没有任何优化。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int i,j,k;
        vector<vector<int>> ans;
        sort(nums.begin(),nums.end());
        for(i=0;i<nums.size();i++)
            for(j=i+1;j<nums.size();j++)
                for(k=j+1;k<nums.size();k++){
                    if(nums[i]+nums[j]+nums[k]==0){
                        ans.push_back({nums[i], nums[j], nums[k]});
                    }
                }
        
        sort(ans.begin(),ans.end());
        ans.erase(unique(ans.begin(),ans.end()), ans.end());
        return ans;
    }
};

结果就是超时!

也是我第一次刷力扣吧,确实能够提升思路

在这里插入图片描述
琢磨了点,但是因为太菜,好几个月没碰算法,没有什么有效的思路,一直脱离不开三层循环框架,于是看了题解,再次感叹题解做法秒!

再次提交做法

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int i,j,k;
        vector<vector<int>> ans;
        // 先排序
        sort(nums.begin(),nums.end());
        for(i=0;i<nums.size();i++){
            //先确定第一个数
            //这个数和上一数不能大小相等
            if(i!=0 && nums[i]==nums[i-1]){
                continue;
            }
            for(j=i+1;j<nums.size();j++){
                if(j!=i+1 && nums[j]==nums[j-1]){
                    continue;
                }

                k = nums.size()-1;
                while(k>j && nums[i]+nums[j]+nums[k]>0){
                    k--;
                }
                if(k==j){
                    break;
                }
                if(nums[i]+nums[j]+nums[k]==0){
                    ans.push_back({nums[i], nums[j], nums[k]});
                }
                
            }

        }
        return ans;
    }
};

以上是我看了题解之后自以为懂了,但是提交之后仍然是超时!!

在这里插入图片描述
然后我又返回去看题解,不得不说还是上次看题解没有真正理解!o(╥﹏╥)o

算法思路

算法思路是这样滴
把三数之和转换成两数之和,也就是在每次循环第一个数时,就相当于把这个数确定下来了,这个时候,再分析剩下两个数的关系,如何让它们仨相加等于0就可以了。
与此同时,还需要注意几个点:

  1. i!=j and j!=k and i!=k
    三个数的下标不同,这个简单,循环的时候让第二个数的下标等于第一个数坐标+1就可
    (例如:j=i+1)

  2. 数组里有重复的数,但是输出要求不能有重复的数组
    首先给原数组排序,让相等的数挨着,才能用nums[j]!=nums[j-1]确保每次选的数之前没有选过。但是,例如:nums[j-1]注意不能和nums[i]相等,因此这个判断条件需要加上当j!=i+1的时候

  3. 时间复杂度的问题
    第一个数和第二个数都是用嵌套循环确定的,从左往右依次选取,时间复杂度已经是N^2了
    如果第三个数再嵌套实现,那还是N^3

    在每次对第一个数已经确定的情况下(假设第一个数为num1),对第二个数进行循环,因为每次都是从左往右,也就是从小到大选,那对第三个数来说:

    1. 如果从左往右选(从小到大),由于第二个数也是从小到大选,假设对于第二个数的某个值来说,存在num3满足num1+num2+num3=0。那么当这一轮结束,j+1,开始找num2’对应的num3’,使满足num1+num2’+num3’=0,此时,num2’肯定>num2,那说明num3’肯定要<num3,但是第三轮的循环,k初始为j+1,也就是从左往右选 ,那么,如果在最差的情况下,num3在n-1的下标处,相当于每次第二轮循环结束之后,k都要从j+1重新从左往右选取,这样下来时间复杂度就还是N^3,没有任何提升,还是AC不了。
    2. 如果从右往左选(从大到小),接着1.的开始找num2’对应的num3’,使满足num1+num2’+num3’=0说起,这时k的初始化为n-1,num2’>num2,需要num3’<num3,这样k就不用再重新初始化了,直接在上一个num3的下标位置再往左走就好,这样k的初始化应该在第二轮循环之前,第一轮循环之后,时间复杂度也就变成了N^2。即,k不是每次在第二个数循环里都需要初始化为k=n-1,(我上一个超时的代码就犯了这个错误

AC代码

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int i,j,k;
        vector<vector<int>> ans;
        // 先排序
        sort(nums.begin(),nums.end());
        for(i=0;i<nums.size();i++){
            //先确定第一个数
            //这个数和上一数不能大小相等
            if(i!=0 && nums[i]==nums[i-1]){
                continue;
            }
            k = nums.size()-1;
            for(j=i+1;j<nums.size();j++){
                if(j!=i+1 && nums[j]==nums[j-1]){
                    continue;
                }

                while(k>j && nums[i]+nums[j]+nums[k]>0){
                    k--;
                }
                if(k==j){
                    break;
                }
                if(nums[i]+nums[j]+nums[k]==0){
                    ans.push_back({nums[i], nums[j], nums[k]});
                }
                
            }

        }
        return ans;
    }
};

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

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

相关文章

Windows 11中查找和删除旧文件的几种方法,总有一种适合你

序言 如果你的电脑存储空间不足,最好的办法就是找到并删除旧的、不需要的文件。Windows 11提供了多种方法来查找这些占用存储空间的项目,我们将在本指南中向你展示这些方法以及如何使用它们。 使用存储感知 存储感知是Windows 11的内置功能,可帮助自动清理旧文件。你可以…

2024年第三届数据统计与分析竞赛(B题)数学建模完整思路+完整代码全解全析

你是否在寻找数学建模比赛的突破点&#xff1f;数学建模进阶思路&#xff01; 详细请查 作为经验丰富的数学建模团队&#xff0c;我们将为你带来2024年第三届数据统计与分析竞赛&#xff08;B题&#xff09;的全面解析。这个解决方案包不仅包括完整的代码实现&#xff0c;还有…

宠物空气净化器性能大比拼,美的、希喂、霍尼韦尔哪个牌子最好!

养猫最头疼的就是家里到处都是猫浮毛&#xff0c;铲屎官想家里干净卫生&#xff0c;就得想办法处理好猫浮毛&#xff0c;不及时处理&#xff0c;浮毛长期飘浮在空气中&#xff0c;对铲屎官的身体很容易造成威胁。针对这个问题&#xff0c;使用专门的宠物空气净化器&#xff0c;…

解析Facebook对当代文化传播的影响力

Facebook作为全球最大的社交媒体平台之一&#xff0c;承载着巨大的文化传播功能&#xff0c;对当代文化产生了深远的影响。从社会交流、价值观念到艺术创作和政治动态&#xff0c;Facebook已经成为了人们获取信息、表达观点和交流想法的重要平台。本文将深入解析Facebook对当代…

源代码加密的十个关键点

源代码加密是一种安全措施&#xff0c;其目的是为了保护软件的源代码不被未授权的个人或实体访问或泄露。源代码是软件应用程序的基础&#xff0c;它包含了程序的逻辑结构、核心算法以及设计理念。由于源代码承载了软件的核心知识和创新&#xff0c;因此它具有极高的商业价值和…

C语言—数据在内存中的存储

1.整数在内存中的存储 文章回顾&#xff08;C语言—操作符详解&#xff09; 整数的2进制表示方式有三种&#xff0c;即原码、反码和补码。 有符号的整数&#xff0c;三种表示方式均有符号位和数值位两部分&#xff0c;符号位都是用0表示“正”&#xff0c;用1表示“负”&…

失眠焦虑的饮食小建议

在快节奏的现代生活中&#xff0c;失眠和焦虑已成为许多人的常见问题。除了寻求专业的心理咨询和医疗帮助外&#xff0c;合理的饮食习惯也是缓解这些症状的重要途径。本文将为大家提供一些关于失眠焦虑的饮食小建议&#xff0c;希望能对大家有所帮助。 一、均衡膳食&#xff0c…

Rhinoceros 8 for Mac(犀牛8 mac版) v8.8.24163中文激活版

Rhino 8是一款功能强大的三维构建软件&#xff0c;它可以帮助用户创建各种类型的3D模型&#xff0c;包括产品设计、建筑设计、工业设计计划等。Rhino 7具有直观的界面和丰富的工具库&#xff0c;让用户可以快速轻松地进行建模、编辑、分析和漂染。 Rhino 8支持多种文件格式的导…

期权和股票有什么区别?

今天带你了解期权和股票有什么区别&#xff1f;股票和期权都是投资产品&#xff0c;但它们却是两种截然不同的交易模式&#xff0c;在开户要求上也有很多差别。 期权和股票有什么区别&#xff1f; 权利与义务&#xff1a; 股票&#xff1a;代表公司的所有权的一部分&#xff…

make和Cmake都有什么区别?(内附使用详解)

Make和Cmake make和Cmake的区别&#xff1a; 角色和功能: make: 是一个构建工具&#xff0c;它的任务是读取 Makefile 文件&#xff0c;并基于这些文件中的指令执行具体的构建操作。Makefile 文件包含了如何构建项目的规则&#xff0c;make 负责解析这些规则并执行必要的命令来…

电脑上好用的能够提醒自己的软件有哪些

在繁忙的工作和生活中&#xff0c;我时常感到头脑中的思绪如同乱麻一般&#xff0c;难以理清。会议、项目截止日期、家庭琐事&#xff0c;这些重要的事务有时会在不经意间从我的记忆中溜走。没有一款提醒软件&#xff0c;我仿佛就像是在没有指南针的海洋中漂泊&#xff0c;时常…

一户一表集中抄表:现代化大都市管理的新模式

1.定义分析 一户一表集中抄表是一种现代化能源管理体系方法&#xff0c;广泛应用于电力工程、供水公司、天然气等行业。这个模式下&#xff0c;每一个用户都有独立的电能表&#xff0c;这种表集中化在一处进行在线数据载入&#xff0c;大大提升了抄水表效率精确性。用这种方式…

贝壳找房: 为 AI 平台打造混合多云的存储加速底座

贝壳机器学习平台的计算资源&#xff0c;尤其是 GPU&#xff0c;主要依赖公有云服务&#xff0c;并分布在不同的地理区域。为了让存储可以灵活地跟随计算资源&#xff0c;存储系统需具备高度的灵活性&#xff0c;支持跨区域的数据访问和迁移&#xff0c;同时确保计算任务的连续…

JAVA代码审计之SQL注入代码审计

前言 SQL注入漏洞是对数据库进行的一种攻击方式。其主要形成方式是在数据交互中&#xff0c;前端数据通过后台在对数据库进行操作时&#xff0c;由于没有做好安全防护&#xff0c;导致攻击者将恶意代码拼接到请求参数中&#xff0c;被当做SQL语句的一部分进行执行&#xff0c;…

containerd: failed to load TOML: /etc/containerd/config.toml

1、启动containerd报错截图如下: 2、解决办法: 2.1 停止containerd服务 systemctl stop containerd 2.2 删除containerd文件 rm -rf /var/lib/containerd/* /var/lib/containers/* 132 yum install docker-ce-20.10.* docker-ce-cli-20.10.* containerd.io -y 133 …

Visual Studio扩展开发

对于Roslyn(编译平台)的扩展 内容来源:https://learn.microsoft.com/zh-cn/dotnet/csharp/roslyn-sdk/tutorials/how-to-write-csharp-analyzer-code-fix 创建项目 解决方案项目介绍 Resources.resx介绍 填入的内容会在错误列表中显示

高考填报志愿选专业,理科生如何选专业?

理科相对比较好选专业&#xff0c;因为院校多&#xff0c;专业多&#xff0c;当然招生名额也多&#xff0c;对于一般普通家庭的学生来说&#xff0c;理科生比文科生的就业前景好。但这是一个就业形势十分严峻的时代&#xff0c;没有谁敢绝对的说自己一定能在某个专业中学到知识…

计算机 SCI期刊,中科院1区TOP,IF=10+,老牌期刊,声誉和口碑上佳!

一、期刊名称 IEEE Transactions on Wireless Communications 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;计算机科学 影响因子&#xff1a;10.4 中科院分区&#xff1a;1区TOP 三、期刊征稿范围 《IEEE Transactions on Wireless Communications》出…

【AI大模型】Transformers大模型库(六):torch.cuda.OutOfMemoryError: CUDA out of memory解决

​​​​​​​ 目录 一、引言 二、CUDA显存超出&#xff08;CUDA out of memory&#xff09; 2.1 概述 2.2 解决方案 2.3 代码示例 2.4 查看显存 三、总结 一、引言 这里的Transformers指的是huggingface开发的大模型库&#xff0c;为huggingface上数以万计的预训练大…

java实战——图书管理项目

文章目录 项目所需要的技术栈项目演示项目准备工作环境准备数据库数据准备 前后端交互分析&#xff08;前端代码我们使用现成&#xff09;图书列表界面的创建查看前端发送的请求根据前端接收的返回值来编写model层根据请求编写controller层根据controller编写Service根据Servic…