大厂算法指南:优选算法 ——双指针篇(下)

大厂算法指南:优选算法 ——双指针篇(上)

  • 前言:双指针简介
  • 一、[611. 有效三角形的个数](https://leetcode.cn/problems/valid-triangle-number/)
    • 1.1 算法思路(排序 + 双指针)
    • 1.2 代码实现
  • 二、[LCR 179. 查找总价格为目标值的两个商品](https://leetcode.cn/problems/he-wei-sde-liang-ge-shu-zi-lcof/)![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/f11acc0359ef4cfc92f1737ae0b85166.png)
    • 2.1 算法思路
    • 2.2 代码实现
  • 三、[15. 三数之和](https://leetcode.cn/problems/3sum/)
    • 3.1 算法思路
    • 3.2 代码实现
  • 四、[18. 四数之和](https://leetcode.cn/problems/4sum/)
    • 4.1 算法思路(排序 + 双指针)
    • 4.2 代码实现

在这里插入图片描述

📕作者简介:非科班在读,纯技术博客分享,致力于C/C++,涉及Python、C/C++、Linux,数据结构,git企业级开发,Mysql等。
📗本文收录于算法指南,旨在帮助读者应对各大互联网大厂笔试题,构建完整的算法体系!
📘相关专栏C语言、C++、数据结构、Linux、前言科技喜欢C/C++/Linux/算法的朋友们可以关注一下哦!
————————————————
版权声明:本文为CSDN博主「小宇成长录」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://editor.csdn.net/md/?not_checkout=1&spm=1011.2124.3001.6183

前言:双指针简介

常⻅的双指针有两种形式,⼀种是对撞指针,⼀种是左右指针。
对撞指针:⼀般⽤于顺序结构中,也称左右指针。

。对撞指针从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼近。
。对撞指针的终⽌条件⼀般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循环),也就是:
◦ left == right (两个指针指向同⼀个位置)
◦ left > right (两个指针错开)

快慢指针:⼜称为⻳兔赛跑算法,其基本思想就是使⽤两个移动速度不同的指针在数组或链表等序列结构上移动。
这种⽅法对于处理环形链表或数组⾮常有⽤。其实不单单是环形链表或者是数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使⽤快慢指针的思想。
快慢指针的实现⽅式有很多种,最常⽤的⼀种就是:

。 在⼀次循环中,每次让慢的指针向后移动⼀位,⽽快的指针往后移动两位,实现⼀快⼀慢。

话不多说,现在来看看大厂们比较有代表性的面试题吧!

一、611. 有效三角形的个数

在这里插入图片描述

1.1 算法思路(排序 + 双指针)

先将数组排序。
我们可以固定⼀个「最⻓边」,然后在⽐这条边⼩的有序数组中找出⼀个⼆元组,使这个⼆元组之和⼤于这个最⻓边。由于数组是有序的,我们可以利⽤「对撞指针」来优化。

  • 设最⻓边枚举到 i 位置,区间 [left, right] 是 i 位置左边的区间(也就是⽐它⼩的区间):
    • 如果 nums[left] + nums[right] > nums[i] ;说明 [left, right - 1] 区间上的所有元素均可以与 nums[right] 构成⽐nums[i] ⼤的⼆元组,满⾜条件的有 right - left 种。此时 right 位置的元素的所有情况相当于全部考虑完毕, right-- ,进⼊下⼀轮判断。
    • 如果 nums[left] + nums[right] <= nums[i] ;说明 left 位置的元素是不可能与 [left + 1, right] 位置上的元素构成满⾜条件的⼆元组。left 位置的元素可以舍去, left++ 进⼊下轮循环。

1.2 代码实现

class Solution {
public:int triangleNumber(vector<int>& nums) {sort(nums.begin(), nums.end());//排序int ret=0;for(int i=nums.size()-1; i>=2; i--){int left=0, right=i-1, target=nums[i];while(left<right){if(nums[left] + nums[right] > target){ret += right-left;right--;}else{left++;}}}return ret;}
};

二、LCR 179. 查找总价格为目标值的两个商品在这里插入图片描述

(https://leetcode.cn/problems/he-wei-sde-liang-ge-shu-zi-lcof/)

2.1 算法思路

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

算法流程如下:

  • 初始化 left , right 分别指向数组的左右两端(这⾥不是我们理解的指针,⽽是数组的下标)
  • 当 left < right 的时候,⼀直循环以下过程:
    • 1.当 nums[left] + nums[right] == target 时,说明找到结果,记录结果,并且返回;

    • 2.当 nums[left] + nums[right] < target 时:

      • 对于 nums[left] ⽽⾔,此时 nums[right] 相当于是 nums[left] 能碰到的最⼤值(别忘了,这⾥是升序数组哈~)。如果此时不符合要求,说明在这个数组⾥⾯,没有别的数符合 nums[left] 的要求了(最⼤的数都满⾜不了你,你已经没救了)。因此,我们可以⼤胆舍去这个数,让 left++ ,去⽐较下⼀组数据;
      • 那对于 nums[right] ⽽⾔,由于此时两数之和是⼩于⽬标值的, nums[right]还可以选择⽐ nums[left] ⼤的值继续努⼒达到⽬标值,因此 right 指针我们按兵不动;
    • 当 nums[left] + nums[right] > target 时,同理我们可以舍去nums[right] (最⼩的数都满⾜不了你,你也没救了)。让 right-- ,继续⽐较下⼀组数据,⽽ left 指针不变(因为他还是可以去匹配⽐ nums[right] 更⼩的数)。

2.2 代码实现

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++;elsereturn {price[left], price[right]};}return {-1, -1};}
};

三、15. 三数之和

在这里插入图片描述

3.1 算法思路

本题与两数之和类似,是⾮常经典的⾯试题。

与两数之和稍微不同的是,题⽬中要求找到所有「不重复」的三元组。那我们可以利⽤在两数之和那⾥⽤的双指针思想,来对我们的暴⼒枚举做优化:

  1. 先排序;
  2. 然后固定⼀个数 a :
  3. 在这个数后⾯的区间内,使⽤「双指针算法」快速找到两个数之和等于 -a 即可。

但是要注意的是,这道题⾥⾯需要有「去重」操作~

  1. 找到⼀个结果之后, left 和 right 指针要「跳过重复」的元素;’
  2. 当使⽤完⼀次双指针算法之后,固定的 a 也要「跳过重复」的元素

3.2 代码实现

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>>  ret;//1. 排序sort(nums.begin(), nums.end());//2. 双指针思路for(int i=nums.size()-1; i>=2; i--){if(nums[i]<0)break;int left =0, right=i-1;while(left<right){if(nums[left] + nums[right] + nums[i] > 0)right--;else if(nums[left] + nums[right] + nums[i] < 0)left++;else{//相等,记录数据;处理相同元素ret.push_back({nums[left], nums[right], nums[i]});left++, right--;//处理相同元素while(left<right && nums[left-1] == nums[left]){left++;}while(left<right && nums[right+1] == nums[right]){right--;}}//处理相同元素,防止重叠while(i >=2 && nums[i] == nums[i-1]){i--;}}}return ret;}
};

四、18. 四数之和

在这里插入图片描述

4.1 算法思路(排序 + 双指针)

a. 依次固定⼀个数 a ;
b. 在这个数 a 的后⾯区间上,利⽤「三数之和」找到三个数,使这三个数的和等于 target - a 即可。

4.2 代码实现

lass Solution
{
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> ret;// 1. 排序sort(nums.begin(), nums.end());// 2. 利⽤双指针解决问题int n = nums.size();for(int i = 0; i < n; ) // 固定数 a{// 利⽤ 三数之和for(int j = i + 1; j < n; ) // 固定数 b{// 双指针int left = j + 1, right = n - 1;long long aim = (long long)target - nums[i] - nums[j];while(left < right){int sum = nums[left] + nums[right];if(sum < aim) left++;else if(sum > aim)right--;else{ret.push_back({nums[i], nums[j], nums[left++], nums[right--]});// 去重⼀while(left < right && nums[left] == nums[left - 1]) left++;while(left < right && nums[right] == nums[right + 1]) right--;}}// 去重⼆j++;while(j < n && nums[j] == nums[j - 1]) j++;}// 去重三i++;while(i < n && nums[i] == nums[i - 1]) i++;}return ret;}
};

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win11+RTX 4070Ti+CUDA12.1+cuDNN12.x+pytorch2.1 环境配置(图文教程)

win11RTX 4070TiCUDA12.1cuDNN12.xpytorch2.1 环境配置&#xff08;图文教程&#xff09; 教程基本信息介绍卸载已安装的CUDA和cuDNN安装CUDA与cuDNN安装 Anaconda安装 pytorch测试 pytorch 是否安装成功 教程基本信息介绍 此教程为本人安装记录&#xff0c;仅供参考 本教程时间…

【机器学习】041_模型开发迭代过程

一、模型开发的一般步骤 1. 明确研究问题 确定问题的组成和结果&#xff0c;明晰问题是分类问题还是回归问题 2. 决定系统总体架构 ①理解数据&#xff1a;采集&#xff08;爬取&#xff09;数据&#xff0c;生成&#xff08;导入&#xff09;数据&#xff0c;进行数据清洗…

【数据结构高阶】红黑树

目录 一、红黑树的概念 二、红黑树的性质 2.1 红黑树与AVL树的比较 三、红黑树的实现 3.1 红黑树节点的定义 3.2 数据的插入 3.2.1 红黑树的调整思路 3.2.1.1 cur为红&#xff0c;f为红&#xff0c;g为黑&#xff0c;u存在且为红 3.2.1.2 cur为红&#xff0c;f为红&am…

uniapp iOS离线打包——运行项目到模拟器报错?

运行项目、打包时报错问题 记录个人在开发过程中遇到的相关问题&#xff0c;后续有时间会不定时更新 文章目录 运行项目、打包时报错问题运行到模拟器报错解决方案 打包报错解决方案 运行到模拟器报错 解决方案 选中项目工程 —> Build Settings 滑动底部 —> User-Defi…

【PyTorch】卷积神经网络

文章目录 1. 理论介绍1.1. 从全连接层到卷积层1.1.1. 背景1.1.2. 从全连接层推导出卷积层 1.2. 卷积层1.2.1. 图像卷积1.2.2. 填充和步幅1.2.3. 多通道 1.3. 池化层&#xff08;又称汇聚层&#xff09;1.3.1. 背景1.3.2. 池化运算1.3.3. 填充和步幅1.3.4. 多通道 1.4. 卷积神经…

【Hive】启动beeline连接hive报错解决

1、解决报错2、在datagrip上连接hive 1、解决报错 刚开始一直报错&#xff1a;启动不起来 hive-site.xml需要配置hiveserver2相关的 在hive-site.xml文件中添加如下配置信息 <!-- 指定hiveserver2连接的host --> <property><name>hive.server2.thrift.bin…

基于SpringBoot+JSP+Mysql宠物领养网站+协同过滤算法推荐宠物(Java毕业设计)

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…

gitbash下载安装

参考教程 零、下载 官网地址 2.43.0win64 链接&#xff1a;https://pan.baidu.com/s/16urs_nmky7j20-qNzUTTkg 提取码&#xff1a;7jaq 一、安装 图标组件&#xff08;Additional icons&#xff09;&#xff1a;选择是否创建桌面快捷方式&#xff1b;桌面浏览&#xff08;Win…

漏刻有时百度地图API实战开发(8)关键词输入检索获取经纬度坐标和地址

在百度地图中进行关键词输入检索时&#xff1a; 在地图页面顶部的搜索框中输入关键词。点击搜索按钮或按下回车键进行搜索。地图将显示与关键词相关的地点、商家、景点等信息。可以使用筛选和排序功能来缩小搜索范围或更改搜索结果的排序方式。点击搜索结果中的地点或商家&…

oops-framework框架 之 日志管理(七)

引擎&#xff1a; CocosCreator 3.8.0 环境&#xff1a; Mac Gitee: oops-game-kit 注&#xff1a; 作者dgflash的oops-framework框架QQ群&#xff1a; 628575875 Logger 作者dgflash针对于oops-framework封装的日志管理类是通过Logger实现的&#xff0c;接口在框架中的定义&…

docker 一键寻找容器在服务器存储位置

docker ps -a找到容器id/容器名称 docker inspect 容器id/容器名称 | grep UpperDir找出该容器在物理机的位置 inspect作用:查看docker详细信息 cd到UpperDir所指向的地址&#xff0c;找到配置文件并修改,到这后,这个位置和你用exec命令进入容器内看到文件是一致的

vue3中关于echars的使用

今天介绍一个好用的插件echars&#xff0c;一个可视化插件Apache ECharts 一、使用步骤 1、安装 npm install echarts --save 2、导入 import * as echarts from echarts 3、正式使用 echars的使用非常的简单&#xff0c;直接点击官网有现成的代码的可用 代码示例 <t…