双指针算法的妙用:提高代码效率的秘密(3)

双指针算法的妙用:提高代码效率的秘密(3)

前言:

小编在昨日讲述了关于双指针算法的两个题目,今日继续分享两个题目的解析,我相信,我只要坚持每天啥刷题,算法能力终究会提高的,下面废话不多说,开始进入今天的代码时间。

文章目录

  • 双指针算法的妙用:提高代码效率的秘密(3)
    • 1.有效三角形的个数
      • 1.1.题目来源
      • 1.2.题目讲解
      • 1.3.题目思路解析
        • 1.3.1.暴力解法
        • 1.3.2.数学思想简化判断三角形
        • 1.3.3.双指针解法
      • 1.4.代码实操
      • 1.5.解题代码
    • 2.查找总价值为目标值的两个商品
      • 2.1.题目来源
      • 2.2.题目讲解
      • 2.3.题目思路讲解
        • 2.3.1.暴力解法
        • 2.3.2.双指针解法
      • 2.4.代码实操
      • 2.5.解题代码
    • 3.总结

正文:

1.有效三角形的个数

1.1.题目来源

老规矩,先展示题目的来源:611. 有效三角形的个数 - 力扣(LeetCode)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.2.题目讲解

本题是想让我们计算一个区间内有效三角形的个数,各位读者看这个题目的时候不要被这个题目的难度给打败,我们如果一直做简单题是没有什么效果的,难题我们总是会在刷题的路上遇到的,这是不可避免的事,我们早点遇到难题才会为我们以后拿下难题作为基础。这个题目的内容大支架就是这样简单的,当然我们看到例题的时候,可以知道这个题目如果有重复的数出现也是没有问题的,因为此时重复的数出现的位置是不一样的,所以自然可以允许三个数重复,下面小编给出这个题目的思路讲解。

1.3.题目思路解析

这个题目就要让我们具备一定的数学基础,首先的话我们要知道如何去判断一个三角形,这个小学我们就学过,如果有读者朋友不知道那就不应该了:对于一个三角形:任意给出两边,两边之和大于第三遍或者是两边之差小于第三边,那就证明出这个就是个三角形,我们依据这个性质,首先会想到一个解法:暴力解法。

1.3.1.暴力解法

无论我们去做哪个算法题,暴力解法往往是我们第一个可以想到的最容易去解决题目的算法,就以这个题目为例子,我们知道了如何去判断一个三角形,只要我们让任意两边之和大于第三遍即可,那我们就可以选择通过循环来完成这个题目,最外层循环是第一个数,第二个循环是第二个数,第三个循环是第三个数,通过三层循环来做到判断一个三角形,对于三角形的判断,我们可以采取分别判断三边来进行判断的操作,不过这样的时间复杂度会变的很恐怖,所以小编不推荐这个判断三角形的方法,具体三角形的判断方法小编会在一会进行叙述,在这里可以先知道我们仅通过判断一次三个数的比较就可以判断出一个三角形,如此做下去,虽然说没有错误,但是时间复杂度会是O(N ^ 3),这个题目包是通过不了的,所以暴力解法out,下面小编先讲述用数学思想简化判断三角形,然后讲述这个题目最好用的解法。

1.3.2.数学思想简化判断三角形

这个理想其实也是很好像的,我们比较一个三角形的大小,正常是判断任意两边之和大于第三边,下面我们可以这么想:我们先选择一个最大的数,让另外两个数和这个数进行比较,如果大于的话我们可以直接判断这是三角形,反着则不是;关于我为什么说这么做就可以判断三角形,听我娓娓道来:此时我们已经知道两个小的数加起来大于第三个数了,如果正常解法的haul,我们就要用两个数之一和大的数相加与另外一个小的数进行比较了,这样的结果是显而易见是大于的,因为两个小的数都大于大的数了,更何谈小的加大的了?所以我们在判断三角形的时候,仅需把两个小的和大的做比较即可,此时就是这个题目用到的数学思想。

1.3.3.双指针解法

这个题目比较好用的解法,其实还是用到双指针的知识进行求解,此时我们就要借助上面的数学思想了,此时因为我们要知道谁是最大的数,所以我们要让数组进行排序,此时我们调用算法库里面的sort()函数即可,之后我们就要讲述一下我们如何使用双指针来进行有效三角形个数的计算:

首先我们需要先把最后一个数定下来(i),它表示在三角形中最大的数,然后我们设置好两个指针,一个指针(left)代表开头的位置,一个指针表示最后一个数前一个的位置(right),下面我拿例一举例子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

之后我们想让left和right位置的数据相加和最大数位置(i)进行比较,如果此时两数之和大于最大位置的数,那么我们中间位置的三角形就不用计算了,因为此时最左边的数最小,此时的它已经和right相加大于最大的数了,那就更不用说比它大的右边的数了,所以此时我们自己计算中间三角形的个数即可,也就是right - left;倘若两数之和小于大数,那么就让left往右边走,直到找到大于第三遍或者左右指针相遇了,此时就结束查找。以上都做完的话,那么就让最大的数往左走,进行剩余区间三角形个数的查找。就以例一为例,此时left + right大于i,所以我们统计二者之差后,让i往前走,right也会跟着往前走,left还是最小位置:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

之后我们进行重复判断完以后就可以找到所有三角形的个数,这就是本题目的思路讲解,下面小编进入代码部分的讲解。

1.4.代码实操

首先,我们需要先给数组排个序,通过sort函数可以轻松解决排序问题,并且设置一个变量来对三角形个数进行计算:

sort(nums.begin(),nums.end());
int count = 0;

之后我们就可以进入主要内容的书写,我们要先完成最大数的循环,此时我们仅需通过一层for循环来解决这个问题,刚开始我们让最大数的位置是数组最后一个位置的数据,然后它的限制条件是它需要大于等于第三个位置的数据,因为第三个位置之前的数在进行判断三角形就完全没有必要了,其代码如下所示:

for(int i = nums.size() - 1 ; i >= 2 ; i--)
{//循环的内容下面讲}

我们在循环体里面就可以进行双指针的书写,其中left是最左位置,right是最大的位置的上一个位置,此时我们还需要用到一个循环,用循环来判断有效三角形的个数,在新的循环体里,我们需要判断此时了left和right之和是否大于最大的数,如果大于的话,我们可以计入它们之间有效三角形的个数,然后结束循环,如果小于的话,让left往右边走,直到left >= right,那么循环结束,此时我们继续进入下一个外层循环,通过双层循环来进行判断有效三角形的个数,此时这个循环体就结束了:

int left = 0,right = i - 1;
while(left < right)
{if(nums[left] + nums[right] > nums[i]){count += right - left;right--;}elseleft++;
}

此时本题目的讲述就结束了,下面我给出完整解题代码,并进入下一个题目的讲述。

1.5.解题代码

class Solution {
public:int triangleNumber(vector<int>& nums) {sort(nums.begin(),nums.end());int count = 0; //统计三角形的个数for(int i = nums.size() - 1 ; i >= 2 ; i--){int left = 0,right = i - 1;while(left < right){if(nums[left] + nums[right] > nums[i]){count += right - left;right--;}elseleft++;}}return count;}
};

2.查找总价值为目标值的两个商品

2.1.题目来源

老规矩,先给出本题的来源:查找总价格为目标值的两个商品

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.2.题目讲解

本题原来其实是剑指offer的一个题目,我找了类似的题目来给各位进行讲解,这个题目其实理解起来是很容易的,它无非就是让我们在一个严格单增的数组里面找到两个数,让这个数刚好等于给定我们的数target,如果找到了就返回这两个数,没有的话就返回空,下面小编进入题目的思想讲解部分。

2.3.题目思路讲解

2.3.1.暴力解法

同样的,这个题目也是有暴力解法的,小编刚开始想到的解题方法就是通过两个循环进行遍历数组,让第一个循环从开头开始,让第二个循环从第一个数的下一个数开始,开始通过两个循环找到两个数的和等于给定的数target,如果循环结束了,就证明没有找到,我们返回一个空就好,这样的解法虽然想起来和写起来是很容易的,但是这样做的话导致时间复杂度变的非常高,由于两次循环,所以复杂度是O(N ^ 2),这么做有时候是通不过题目的,我们要学会从题目中找到简单的方法,这里我们可以知道此时的数组是单调递增的,我们可以通过这个性质,加上暴力解法的思想来进行题目的解答,下面小编给出这个题目的优选算法。

2.3.2.双指针解法

本题目其实用双指针做起来是最舒服的,当然,有的读者朋友也可以用二分解法来解决这个问题,不过这个题目,小编还是很推荐用双指针的,此时我们仅需一个循环就可以解决这个问题,双指针的用法如下所示:

  1. 首先我们需要两个指针,一个指向开头(left),一个指向结尾(right)。
  2. 让开头和结尾相加,如果加起来的数大于目标值target,那么我们就让右边的指针往左走,这么做的原因是因为和此时数组性质有关,此时的数组是单增的,所有右边的数肯定是最大的,此时我们二数之和很大,所以我们让大的数减小;如果此时加起来的数小于target,那么就让左边的数往右走,道理和前面类似,我就不多家赘述了。
  3. 最后我们如果找到了两个数,使它们加起来等于target,那么我们直接返回这两个数就好;如果循环结束了,证明没有两个数加来为target,那么我们就返回空就好。

这便是这个题目的思路讲解,希望各位在看完我的思路之后自己敲一遍代码,如果认为我说的不太懂的话,评论区dd我或者直接私信我,我会重新把思路讲解部分写一遍的,来帮助各位理解,下面小编进入代码讲解部分。

2.4.代码实操

首先,我们准备两个指针,一个指向开头(left),一个指向结尾(right),另外我们在设置一个vector容器,用来存储两个数:

vector<int> s1;
int left = 0,right = price.size() - 1;

之后我们就进入一个循环,循环的条件自然是左指针要小于右指针,我们先来判断此时的两数之和和target之间的关系,如果小于的haul,那么让left往右走;如果大于的话,让right往左走;如果相等的haul,让s1存储这两个数,存储结束后直接返回s1即可,如果循环结束以后没有找到两个数的话,那么直接返回s1(此时为空)即可,下面给出相关代码:

while(left < right)
{if(price[left] + price[right] < target)left++;else if(price[left] + price[right] > target)right--;else{s1.push_back(price[left]);s1.push_back(price[right]);return s1;}
}
return s1;

此时这个题目的代码我们就写完了,下面我展示本题目的所有代码:

2.5.解题代码

class Solution {
public:vector<int> twoSum(vector<int>& price, int target) {vector<int> s1;int left = 0,right = price.size() - 1;while(left < right){if(price[left] + price[right] < target)left++;else if(price[left] + price[right] > target)right--;else{s1.push_back(price[left]);s1.push_back(price[right]);return s1;}}return s1;}
};

3.总结

本篇文章到这也就全部结束了,希望各位好好理解我讲述的两道算法题,我会坚持每日两道算法题的更新,希望各位读者朋友在看完以后,如果我文章有一些错误的话,及时在评论区点出或者私信我,我定会及时修改,讲题的时光总是很短暂,那么各位大佬们,我们下一篇文章见啦~
在这里插入图片描述

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

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

相关文章

动力商城-03 Idea集成apifox Mybatis-Plus字段策略

1.Idea下载apifox插件 2.新建令牌放入Idea 3.右键上传到对应接口 4.设置前置url 插件能够自动识别swagger注解 Mybatis-Plus字段策略 1、FieldStrategy作用 Mybatis-Plus字段策略FieldStrategy的作用主要是在进行新增、更新时&#xff0c;根据配置的策略判断是否对实体对…

11.11--final关键字和抽象类

一 java 1.final 关键字-----放在 访问修饰符后面 1&#xff09;防止被继承 2&#xff09;防止 父类方法 被重写 3&#xff09;防止 类中的 属性 被修改 4&#xff09;防止 局部属性 被修改 1.2.细节 1&#xff09;final 修饰属性 必须赋初值 ------------------------------…

IntelliJ+SpringBoot项目实战(三)---基于源代码直接生成漂亮的接口文档

在SpringBoot中可以集成代码插件自动生成接口文档&#xff0c;而且生成的文档很漂亮&#xff0c;除了接口功能介绍、传入参数、响应参数&#xff0c;还具体类似postman的功能&#xff0c;可调用接口进行测试&#xff0c;另外还可以下单WORD版、.md,html格式的文档。下面我们先看…

TemplatesImpl 在Shiro中的利用链学习1

一、前言 在前面的学习中&#xff0c;我们学习了CC1、CC6链&#xff0c;其中CC1链受限于Java8u71版本&#xff0c;而CC6则是通杀的利用链&#xff1b;后来又将 TemplateImpl 融入到 CommonsCollections 利用链中&#xff0c;绕过了 InvokerTransformer 不能使用的限制&#xf…

中仕公考:2025年省考请注意!

打算参加25年省考的考生们注意啦!如果打算参加2025年公务员省考&#xff0c;从这个时间点开始备考刚刚好&#xff0c;如果还不知道怎么备考的&#xff0c;看这篇就够了! 省考流程&#xff1a; 网上报名——资格审查——确认缴费——查看报名序号——准考证打印——笔试——成…

开发RAG应用,你必须知道的7个Embedding模型

在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;Embedding模型是将文本数据转化为数值向量的核心技术&#xff0c;从而让计算机能够便捷地衡量文本间的语义关联&#xff0c;这种表示法已成为多种基础NLP任务的核心&#xff0c;如文本相似度判定、语义搜索、信息检索…

基于Java+SpringBoot学生成绩管理系统

一、作品包含 源码数据库设计文档全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据库&…

Kong API网关,微服务架构中,你看到就不想错过的选型

今天&#xff0c;很多公司都采用微服务架构来处理复杂业务&#xff0c;但随着服务数量增加&#xff0c;API管理成了一项繁重任务。Kong API网关&#xff0c;作为一款高性能的开源API网关&#xff0c;给开发者带来了极大便利。它不仅可以简化API的调用和管理&#xff0c;还拥有丰…

计算机毕业设计 | springboot+vue汽车修理管理系统 汽修厂系统(附源码)

1&#xff0c;项目背景 在如今这个信息时代&#xff0c;“汽车维修管理系统” 这种维修方式已经为越来越多的人所接受。在这种背景之下&#xff0c;一个安全稳定并且强大的网络预约平台不可或缺&#xff0c;在这种成熟的市场需求的推动下&#xff0c;在先进的信息技术的支持下…

使用京东API接口进行支付结算有哪些注意事项?

用京东API接口进行支付结算时&#xff0c;需要注意以下几个事项&#xff1a; 遵守京东开放平台规定&#xff1a;在使用京东API接口时&#xff0c;必须遵守京东开放平台的相关规定&#xff0c;不得滥用接口或进行非法操作。 保护用户隐私&#xff1a;为了保护用户隐私&#xff…

全国宪法宣传周答题活动怎么做

在12月4日全国宪法宣传周即将到来之际&#xff0c;越来越多的企业单位开始举办线上知识竞赛答题活动&#xff0c;以下是一个知识竞赛答题小程序的基本功能&#xff1a; 一、了解活动信息&#xff1a;确定答题活动的开始时间、结束时间以及是否分阶段进行等。不同的答题活动时…

【debug】QT 相关问题error汇总 QT运行闪退 QT5升级到QT6注意要点

总结一下碰到过的所有问题error以及解决方案 如果这个文档未帮助到你&#xff0c;仍有bug未解决&#xff0c;可以在下方评论留言&#xff0c;有偿解决。 qt的UI更新之后构建后发现没有变化 取消项目中的Shadow build的勾选&#xff0c;作用是取消影子构建&#xff0c;此后构建目…

信捷 PLC C语言 POU 指示灯交替灭1秒亮1秒

1.在全局变量表中定义2个定时器变量timer1,timer2 名称 类型 timer1 TMR_FB False -- False False timer2 TMR_FB False -- False False ot BOOL False -- False False ot表示指示灯 2.新建pou…

【Linux进程篇3】说白了,Linux创建进程(fork父子进程)也就那样!!!

--------------------------------------------------------------------------------------------------------------------------------- 每日鸡汤&#xff1a;没人可以好运一生&#xff0c;只有努力才是一生的护身符&#xff0c;不放弃、不辜负。 -----------------------…

使用服务器时进行深度学习训练时,本地必须一直保持连接状态吗?

可以直接查看方法&#xff0c;不看背景 1.使用背景2. 方法2.1 screen命令介绍2.2 为什么要使用screen命令2.3 安装screen2.4 创建session2.5 查看session是否创建成功2.6 跳转进入session2.7 退出跑代码的session2.8 删除session 1.使用背景 我们在进行深度学习训练的时候&…

防火墙笔记地十二天

1.IPSEC协议簇 IPSEC协议簇 --- 基于网络层的&#xff0c;应用密码学的安全通信协议组 IPV6中&#xff0c;IPSEC是要求强制使用的&#xff0c;但是&#xff0c;IPV4中作为可选项使用 IPSEC可以提供的安全服务 机密性 --- 数据加密 完整性 --- 防篡改 可用性 数据源鉴别 -…

即时设计:Sketch的云端版本控制

设计师们经常面临的一个挑战是设计软件的频繁更新&#xff0c;尤其是Sketch这类流行工具。每次更新可能会修复一些旧bug并增加新功能&#xff0c;但同时也可能导致与旧版本的不兼容问题&#xff0c;尤其是在不同工作环境中的电脑性能差异可能导致文件兼容性问题。那么&#xff…

什么是网络安全CTF有何意义?该如何入门?

什么是网络安全CTF?有何意义 &#xff1f;该如何入门 &#xff1f; 什么是网络安全CTF? CTF在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式。它起源于1996年DEFCON&#xff0c;以代替之前通过互相发起真实攻击进行技术比拼的方式。发展至今&#xff…

【Window主机访问Ubuntu从机——Xrdp配置与使用】

使用Xrdp在Window环境下远程桌面访问Ubuntu主机 文章目录 Ubuntu安装图形化界面Ubuntu安装Xrdp通过网线连接两台主机Window主机有线连接配置Ubuntu从机设置测试有线连接 Window主机打开远程桌面功能参考文章总结 Ubuntu安装图形化界面 sudo apt update sudo apt upgrade sudo …

Python-基础语法·上(2)

目录 常量和表达式 变量的语法 定义变量 使用变量 变量的类型 整型与浮点型 字符串 布尔 为什么要有这么多类型? 动态类型特性 注释 输入输出 通过控制台输出 通过控制台输入 运算符 算术运算符 关系运算符 逻辑运算符 赋值运算符 其他 python的一些小练…