《算法闯关指南:优选算法-双指针》--05有效三角形的个数,06查找总价值为目标值的两个商品

《算法闯关指南:优选算法-双指针》--05有效三角形的个数,06查找总价值为目标值的两个商品

🔥草莓熊Lotso:个人主页

❄️个人专栏:《C++知识分享》《Linux 入门到实践:零基础也能懂》

生活是默默的坚持,毅力是永久的享受。


🎬博主简介:


目录

前言:

05.有效三角形的个数

解法:(排序+双指针)

算法思路:

C++代码演示:

算法总结&&笔记展示:

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

解法:(双指针-对撞指针)

算法思路:

C++代码演示:

算法总结&&笔记展示:


前言:

聚焦算法题实战,系统讲解三大核心板块:优选算法:剖析动态规划、二分法等高效策略,学会寻找“最优解”。 递归与回溯:掌握问题分解与状态回退,攻克组合、排列等难题。 贪心算法:理解“局部最优”到“全局最优”的思路,解决区间调度等问题 内容以题带点,讲解思路与代码实现,帮助大家快速提升代码能力。

05.有效三角形的个数

题目链接:

611. 有效三角形的个数 - 力扣(LeetCode)

题目描述:

题目示例:

解法:(排序+双指针)

暴力枚举的方法还是不在这里展示了,大家可以自己写写,但是肯定是过不了的。

算法思路:

  先将数组排序。

  判断三角形的优化方法:

  • 如果能构成三角形,需要满足任意两边之和大于第三边。但是实际上只需要让较小的两条边之和大于第三边即可

根据【上述优化思想】我们可以固定一个【最长边】,然后在比这条边小的有序数组中找出一个二元组,使得这个二元组之和大于这个最长边。由于数组是有序的,我们可以利用【对撞指针】来优化。

设最长边枚举到 i 位置 ,区间 【left,right】 是 i 位置左边的区间(也就是比它小的区间):

1.如果 nums[left] + nums[right] > nums[i];

  • 说明【left,right-1】区间上的所有元素均可以与 nums[right] 构成比 nums[i] 大的二元组
  • 满足条件的有 right - left
  • 此时 right 位置的元素的所有情况相当于全部考虑完毕,right--,进入下一轮判断

2.如果 nums[left] + nums[right] <= nums[i]

  • 说明 left 位置的元素是不可能与 【left+1,right】位置上的元素构成满足条件的二元组
  • left 位置的元素可以舍去, left++ 进去下轮循环

C++代码演示:

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

算法总结&&笔记展示:

笔记字有点丑,大家见谅:


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

题目链接:

LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode)

题目描述:

题目示例:

解法:(双指针-对撞指针)

暴力枚举还是会超时,这里就不展示了。

算法思路:

  注意到本题是升序的数组,因此可以用【对撞指针】优化时间复杂度。

算法流程:(附带算法分析,为什么可以使用对撞指针):

1.初始化 left,right 分别指向数组的左右两端(这里不是我们理解的指针,而是数组的下标)

2.当 left < right 的时候,一直循环

        2.1当 nums[left] + nums[right] == target 时,说明找到结果,记录结果,并且返回;

        2.2当 nums[left] + nums[right] < target 时:

  • 对于 nums[left] 而言,此时 nums[right] 相当于是 nums[left] 能碰到的最大值(别忘了,这里是升序数组哈~)。如果此时不符合要求,说明在这个数组里面,没有别的数符合 nums[left] 的要求了(最大的数满足不了你,你已经没救了)。因此,我们可以大胆舍去这个数。让 left++,去比较下一组数据;
  • 那对于 nums[right] 而言,由于此时两数之和是小于目标值的, nums[right] 还可以选择比 nums[left] 大的值继续努力达到目标值,因此 right 指针我们按兵不动;

3.当 nums[left] + nums[right] > target 时。同理我们可以舍去 nums[right](最小的数都满足不了你,你也没救了)。让 right-- ,继续比较下一组数据,而 left 指针不变(因为他还是可以去匹配比 nums[right] 更小的数)

C++代码演示:

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

算法总结&&笔记展示:

笔记字有点丑,大家见谅:


往期回顾:

结语:本篇博客介绍了两个基于双指针算法的高效解题方法。强调排序预处理和指针移动策略在优化算法中的关键作用。如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。

✨把这些内容吃透超牛的!放松下吧✨
ʕ˘ᴥ˘ʔ
づきらど


Read more

Python 爬虫:自动获取小说内容

一、前言 在 Python 中,使用爬虫获取网络信息是一项非常实用的技能。本教程将以自动获取小说《斗罗大陆》为例,带你完整走一遍爬虫流程,让你对 “发送请求 — 解析数据 — 保存内容” 有清晰的理解。(ps:本教程仅用于技术学习与交流,在进行任何网络爬取前,请遵循相关法律法 规,尊重版权) 二、爬虫核心四步 一个基础的爬虫任务,通常可以拆解为以下四个关键步骤: 1.如何发送请求:使用python库向服务器发起网络请求 2.发送给谁:明确目标资源的URL地址 3.怎么伪装自己:设置请求头,模拟正常浏览器行为,避免被识别为爬虫 4.响应信息处理:接收服务器返回的数据,并从中提取有效内容 三、环境准备 我们将使用两个核心库来完成这个任务: ·requests:用于发送HTTP请求,获取网页源代码 ·lxml:用于高效解析HTML、XML文档,提取我们需要的数据

By Ne0inhk
卷积神经网络(CNN)进阶:经典架构解析与实战开发

卷积神经网络(CNN)进阶:经典架构解析与实战开发

卷积神经网络(CNN)进阶:经典架构解析与实战开发 💡 学习目标:掌握CNN的经典进阶架构设计思路,理解不同架构的核心创新点,能够基于经典架构开发定制化图像任务模型。 💡 学习重点:LeNet-5、AlexNet、VGGNet、ResNet的核心结构与改进逻辑,基于PyTorch实现ResNet-50并完成图像分类任务。 49.1 卷积神经网络进阶的核心驱动力 卷积神经网络从最初的简单结构发展到深度模型,核心驱动力是解决深层网络的性能瓶颈和提升特征提取的效率与精度。 在早期CNN的应用中,研究人员发现两个关键问题: 1. 网络深度增加到一定程度后,会出现梯度消失或梯度爆炸问题,导致模型无法收敛。 2. 简单堆叠卷积层的方式,会造成特征冗余和计算资源浪费,模型泛化能力受限。 ⚠️ 注意:CNN的进阶过程不是单纯的“堆层数”,而是通过结构创新、参数优化和训练技巧的结合,实现性能的突破。 ✅ 结论:经典CNN架构的每一次升级,都针对当时的技术痛点提出了创新性解决方案,掌握这些方案的设计思路,比记住网络结构更重要。 49.2 经典CNN架构深度解析 49.2.1

By Ne0inhk
Spring Boot 实战:MyBatis 操作数据库(上)

Spring Boot 实战:MyBatis 操作数据库(上)

—JavaEE专栏— Spring Boot 实战:MyBatis 操作数据库(上) 摘要 本文深度解析了 Spring Boot 环境下 MyBatis 的集成与应用。通过回顾传统 JDBC 的局限性,详细展示了 MyBatis 在日志配置、CRUD 操作、自增主键返回及多表查询中的实战用法。同时,文章深入探讨了 #{} 与 ${} 的底层预编译差异及安全风险,并分享了企业级开发中的数据库命名规范与 Druid 连接池配置,助力开发者构建稳健的持久层架构。 文章目录 * Spring Boot 实战:MyBatis 操作数据库(上) * 摘要 * @[toc] * 1. 为什么持久层开发需要 MyBatis? * 1.1 传统 JDBC 的局限性 * 1.2

By Ne0inhk

前端检查内存泄露

前言 前端应用的内存泄露,指不再使用内存未被释放,导致页面占用内存持续增长,轻则引发页面卡顿,加载缓慢,重则导致浏览器崩溃, 尤其在单页应用SPA中,路由切换频繁但内存不回收,问题会被无限放大,比如用户长时间使用某后台管理系统,可能出现操作响应式延迟,甚至需要强制刷新才能恢复,这很可能是内存泄露在"作祟" 一. 前端常见的内存泄露场景 1. 意外的全局变量:未声明的变量(如a = 10而非let a = 10)会挂载到window上,页面不刷新就不会释放; 2. 闭包滥用:闭包会保留对外部作用域的引用,若长期持有 DOM 或大型对象,会导致内存无法回收(如未清理的事件监听回调) ; 3. 未清理的 DOM 引用:删除 DOM 节点后,仍保留其引用(如let el =       document.getElementById('test&

By Ne0inhk