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

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

数组——双指针

三数之和

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

错误做法

三重循环框架,最浅显的思路,复杂度是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;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第十五篇——条件熵和信息增益:你提供的信息到底值多少钱?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 通过这篇文章&#xff0c;我知道了条件熵和信息增益&#xff1b;如果你试…

水电站大坝安全监测工作详解

水电站大坝安全监测是确保大坝结构安全和操作安全的关键组成部分。本文将详细解释水电站大坝安全监测的9项主要工作内容&#xff0c;帮助理解其重要性和执行过程。 1) 现场监测 现场监测是水电站大坝安全监测的首要步骤。监测人员需要定期对大坝的物理结构进行检查&#xff0c;…

vite构建的ts项目配置src别名@

一、安装types/node npm install types/node 二、vite.config.ts 文件中配置以下内容 resolve: {alias: {: path.resolve(__dirname, ./src),},}, 三、 tsconfig.json 文件中compilerOptions下配置以下内容 /* 配置 */"baseUrl": ".","paths":…

【Python】详解pandas库中pd.merge函数与代码示例

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主。 &#x1f913; 同时欢迎大家关注其他专栏&#xff0c;我将分享Web前后端开发、人工智能、机器学习、深…

高考志愿填报秘籍:个人篇

选择适合自己的大学和专业&#xff0c;对广大考生来说至关重要。从某种程度上来说&#xff0c;决定了考生未来所从事的行业和发展前景。为了帮助广大考生更加科学、合理地填报志愿&#xff0c;选择适合自己的大学和专业&#xff0c;本公众号将推出如何用AI填报高考志愿专栏文章…

清远mes系统开发商 盈致科技

清远MES系统开发商盈致科技为企业提供专业的MES系统解决方案&#xff0c;帮助企业实现生产过程的数字化管理和优化。盈致科技的服务范围包括但不限于以下方面&#xff1a;MES系统定制开发&#xff1a;盈致科技可以根据清远企业的实际需求定制开发适合的MES系统&#xff0c;满足…

defer关键字

【1】defer关键字的作用&#xff1a; 在函数中&#xff0c;程序员经常需要创建资源&#xff0c;为了在函数执行完毕后&#xff0c;及时的释放资源&#xff0c;Go的设计者提供defer关键字 【2】案例展示&#xff1a; 【3】代码变动一下&#xff0c;再次看结果&#xff1a; 发…

智慧大屏是如何实现数据可视化的?

智慧大屏&#xff0c;作为数据可视化的重要载体&#xff0c;已在城市管理、交通监控、商业运营等领域广泛应用。本文旨在阐述智慧大屏实现数据可视化的关键技术和方法&#xff0c;包括数据源管理、数据处理、视觉编码、用户界面与交互设计等。 大屏通过接入企业内部的数据库系…

openlayers 绘图功能,编辑多边形,modify组件的使用(三)

前两篇介绍了 openlayers 中 draw 的使用&#xff0c;自定义了绘制中和绘制结束后的样式&#xff0c;绘制结束后可以获取到绘制图形的featue或者进一步获取轮廓坐标(如下)&#xff0c;可以进行坐标保存或者将feature添加到其他层进一步自定义显示 draw.value.on("drawend…

arxiv提交报错解决指南

- 编译时无错误 - 所有文件和图片文件都在同一目录下 - 生成.bbl文件 overleaf将参考文献格式bib转bbl&#xff08;bibitem&#xff09;_overleaf bbl文件-CSDN博客 - .tex文件、.bib文件、.bbl文件 的文件名要一致&#xff0c;修改.bib文件名记得在.tex文件中修改bibliograp…

如何导出数据库中数据表或查询结果的数据:支持大数据量(以MySQL和SQLynx为例)

MySQL的数据导出是一个操作非常频繁的任务&#xff0c;也是数据的存储和传输比较重要的一种方式&#xff0c;本文主要以SQLynx为例来介绍MySQL的数据如何导出。 目录 1 操作步骤 步骤 1&#xff1a;登录SQLynx 步骤 2&#xff1a;选择数据库和表 步骤 3&#xff1a;执行查询…

BL104钡铼多协议采集网关助力企业智能化转型

BL104钡铼多协议采集网关&#xff08;PLC物联网关BL104&#xff09;是为满足工业环境需求而设计的专业工业级协议转换网关。它在企业智能化转型过程中扮演着关键角色&#xff0c;为企业提供了高效、稳定的通信解决方案&#xff0c;助力企业实现智能化转型。 首先&#xff0c;P…

【Linux】运维-Kubernetes(k8s)应用介绍及使用-了解

一、介绍 Kubernetes&#xff0c;也被称为K8s或Kube&#xff0c;是谷歌推出的业界最受欢迎的容器编排器。 K8s是一个架构良好的分布式系统的例子。它将集群中的所有机器都视为单个资源池的一部分。 K8s与其他成熟的分布式系统一样&#xff0c;有两层&#xff1a;头节点和工作节…

opencv-python(八)

import cv2 import numpy as npheight 160 width 280 image np.zeros((height, width),np.uint8) cv2.imshow(image,image) cv2.waitKeyEx(0) cv2.destroyAllWindows() 二维数组代表一幅灰度图像。 import cv2 import numpy as npheight 160 width 280 image np.zeros((he…

什么是无头浏览器以及其工作原理?

如果您对这个概念还不熟悉&#xff0c;那么使用无头网络浏览器的想法可能会让您感到不知所措。无头浏览器本质上与您熟悉的网络浏览器相同&#xff0c;但有一个关键区别&#xff1a;它们没有图形用户界面 (GUI)。这意味着没有按钮、选项卡、地址栏或视觉显示。 相反&#xff0c…

译译交友项目介绍

一、 项目背景 随着社会的进步&#xff0c;英语作为一种国际语言&#xff0c;很多人都在学习英语&#xff0c;然而现在很多人都会因为学习英语而烦恼&#xff0c;有时还会因为是一个人学习而感到枯燥。面对情绪的低落&#xff0c;往往会使学习更困难。因此&#xff0c;我打造了…

2024 AI智算产业趋势,数据智能时代的到来(免费下载)

【1】关注公众号<方案驿站> 【2】私信发送 2024AI智算产业趋势展望 【3】获取本方案PDF下载链接&#xff0c;直接下载即可。 如需下载本方案PPT/WORD原格式&#xff0c;诚挚邀请您微信扫描以下二维码加入方案驿站知识星球&#xff0c;获取上万份PPT/WORD解决方案&…

Ubuntu系统中网易云音乐编译安装

项目地址&#xff1a; netease-cloud-music-gtk: Linux 平台下基于 Rust GTK 开发的网易云音乐播放器 目录 1.README.md中按照步骤来 2.安装git 3.报错 sudo apt install cmake sudo apt-get install libdbus-1-dev sudo apt install dnf sudo dnf install gettext 继…

2024年山西泵管阀展览会11月8日开展

2024中国&#xff08;山西&#xff09;国际水务科技博览会 暨水处理技术设备与泵管阀展览会 时间&#xff1a;2024年11月8-10日 地点&#xff1a;山西潇河国际会展中心 经研究&#xff0c;由山西省水处理行业协会、山西省水暖阀门商会、山西省固废产业协会联合主办的2024…

防火墙安全管理

大多数企业通过互联网传输关键数据&#xff0c;因此部署适当的网络安全措施是必要的&#xff0c;拥有足够的网络安全措施可以为网络基础设施提供大量的保护&#xff0c;防止黑客、恶意用户、病毒攻击和数据盗窃。 网络安全结合了多层保护来限制恶意用户&#xff0c;并仅允许授…