【基础算法】——双指针算法

文章目录

  • 一、算法原理
  • 二、算法实战
    • 1. 力扣283 移动零
    • 2. 力扣1089 复写零
    • 3. 力扣15 三数之和
    • 4. 力扣18 四数之和
  • 三、总结


一、算法原理

双指针算法是指在遍历对象的过程中不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。常见的双指针算法有两种:

  • 在一个序列里,用两个指针维护一段区间
  • 在两个序列里,一个指针指向一个序列,另外一个指针指向另外一个序列,来维护某种次序。

💕 算法模板

for (int i = 0, j = 0; i < n; i ++ )  // j从某一位置开始,不一定是0
{while (j < i && check(i, j)) j ++ ;// 具体问题的逻辑
}
常见问题分类:(1) 对于一个序列,用两个指针维护一段区间,比如快排的划分过程(2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作

二、算法实战

1. 力扣283 移动零

在这里插入图片描述
题目链接

算法原理:

在这里插入图片描述

代码实现:

class Solution {
public:void moveZeroes(vector<int>& nums) {for(int dest = -1, cur = 0; cur < nums.size(); cur++)if(nums[cur])swap(nums[++dest], nums[cur]);}
};

2. 力扣1089 复写零

在这里插入图片描述
复写零

算法原理:

在这里插入图片描述

代码实现:

class Solution {
public:void duplicateZeros(vector<int>& arr) {//从前向后遍历,寻找cur和dest的位置int dest = -1, cur = 0, n = arr.size();for(cur = 0; cur < n; cur++){if(arr[cur] == 0)dest+=2;elsedest++;if(dest >= n - 1)break;}if(dest == n){arr[n - 1] = 0;dest-=2, cur--;}while(cur >=0 && dest >= 0){if(arr[cur] == 0)arr[dest--] = 0;arr[dest--] = arr[cur];cur--;}}
};

3. 力扣15 三数之和

在这里插入图片描述
三数之和

算法原理:

本题我们采用 “排序+双指针” 的思想。先将数组排序,用一层循环来枚举第一个数,当我们确定第一个元素后,另外两个元素n2+n3之和就变成了一个定值。当n2增大时n3减小,当n2减小时n3增大。

这样我们就可以在确定第一个元素后,运用双指针来同时确定第二个和第三个元素的值。当然这里我们一定要注意去重的问题,在枚举的过程中就将去重的工作顺便做了即可。

代码实现:

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {int n = nums.size();sort(nums.begin(), nums.end());vector<vector<int>> ret;if(nums[0] > 0 || nums[n - 1] < 0 || n < 3)return ret;if(nums[0] == 0 && nums[n - 1] == 0)return {{0,0,0}};//双指针算法for(int i = 0; i < n - 2; i++){//去重if(i && nums[i] == nums[i - 1])continue;if(nums[i] > 0)break;int left = i + 1, right = n - 1;while(left < right){int sum = nums[i] + nums[left] + nums[right];if(sum < 0)left++;else if(sum > 0)right--;else{ret.push_back({nums[i], nums[left], nums[right]});left++,right--;// 去重while(left < right && nums[left] == nums[left - 1])left++;while(left < right && nums[right] == nums[right + 1])right--;}}}return ret;}
};

4. 力扣18 四数之和

在这里插入图片描述
四数之和

算法原理:

四数之和可以在三数之和的基础上做一下修改,三数之和通过双指针解法可以将时间复杂度降到O(n2),四数之和通过双指针的方法可以将时间复杂度降到 O(n3)。具体方法为:

  • 外面双层循环,代表四个数中的前两个数。
  • 里面为一首一尾双指针,代表四个数中的后两个数,双指针逐步往中间移动,直至相遇。

代码实现:

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {int n = nums.size();sort(nums.begin(), nums.end());vector<vector<int>> ret;for(int i = 0; i < n - 3; i++){if(i && nums[i] == nums[i - 1])continue;for(int j = i + 1; j < n - 2; j++){if(nums[j] == nums[j - 1] && j != i + 1)continue;long long sum = (long long)target - nums[i] - nums[j];int left = j + 1, right = n - 1;while(left < right){if(nums[left] + nums[right] < sum)left++;else if(nums[left] + nums[right] > sum)right--;else{ret.push_back({nums[i], nums[j], nums[left], nums[right]});left++,right--;while(left < right && nums[left] == nums[left - 1])left++;while(left < right && nums[right] == nums[right + 1])right--;}}}}return ret;}
};

三、总结

双指针算法的用途非常的广泛,在数组和链表的操作中是非常常见的,当我们运用双指针时,需要找到目标对象的性质——单调性,当然也必须别忘了指针i和指针j的范围更新问题。最后,多刷题、多总结才能将其运用得当哦!

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

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

相关文章

Tomcat服务器下载安装及配置教程(IDEA中使用Tomcat)

目录 友情提醒第一章、Tomcat下载与安装1.1&#xff09;Tomcat介绍1.2&#xff09;官网下载 第二章、Tomcat配置环境变量2.1&#xff09;windows环境变量配置2.2&#xff09;验证Tomcat配置是否成功2.3&#xff09;报错解决 第三章、IDEA整合Tomcat3.1&#xff09;打开IDEA开发…

【深度学习笔记】随机梯度下降法

本专栏是网易云课堂人工智能课程《神经网络与深度学习》的学习笔记&#xff0c;视频由网易云课堂与 deeplearning.ai 联合出品&#xff0c;主讲人是吴恩达 Andrew Ng 教授。感兴趣的网友可以观看网易云课堂的视频进行深入学习&#xff0c;视频的链接如下&#xff1a; 神经网络和…

springboot项目创建整个完成过程和注意事项

1&#xff1a;application.yml文件配置 server:port: 8088servlet:context-path: /test spring:datasource:name: text #????url: jdbc:mysql://localhost:3306/dsdd?serverTimezoneGMT&useUnicodetrue&characterEncodingutf-8&useSSLtrueusername: root #…

Rust 数据类型 之 结构体(Struct)

目录 结构体&#xff08;Struct&#xff09; 定义与声明 结构体定义 结构体实例 结构体分类 单元结构体&#xff08;Unit Struct&#xff09; 元组结构体&#xff08;Tuple Struct&#xff09; 具名结构体&#xff08;Named Struct&#xff09; 结构体嵌套 结构体方法…

【后端面经】前言汇总(0)

文章目录 一、机会是留给有准备的人二、课程设计第一部分:微服务架构第二部分:数据库与 MySQL第三部分:消息队列第四部分:缓存所谓缓存用得好,性能没烦恼。第五部分:NoSQL三、总结一、机会是留给有准备的人 近两年互联网行业增速放缓,ChatGPT 又引发了一波新的 AI 浪潮,…

使用ffmpeg合并视频遇到的坑

下面以Linux环境介绍为主 1.ffmpeg可执行命令不同的环境是不同的&#xff0c;Linux在执行命令前还需要授权。 2.合并视频命令&#xff1a; 主要命令: {} -f concat -auto_convert 0 -safe 0 -i {} -y -c:v copy 坑一&#xff1a;其中第一个花括号替换的是可执行命令所在的…

【GitOps系列】使用Kustomize和Helm定义应用配置

文章目录 使用 Kustomize 定义应用改造示例应用1.创建基准和多环境目录2.环境差异分析3.为 Base 目录创建通用 Manifest4.为开发环境目录创建差异 Manifest5.为预发布环境创建差异 Manifest6.为生产环境创建差异 Manifest 部署 Kustomize 应用部署到开发环境部署到生产环境 使用…

OpenCv (C++) 使用矩形 Rect 覆盖图像中某个区域

文章目录 1. 使用矩形将图像中某个区域置为黑色2. cv::Rect 类介绍 1. 使用矩形将图像中某个区域置为黑色 推荐参考博客&#xff1a;OpenCV实现将任意形状ROI区域置黑&#xff08;多边形区域置黑&#xff09; 比较常用的是使用 Rect 矩形实现该功能&#xff0c;代码如下&…

打造i-SMART智能网联平台,亚马逊云科技助力上汽快速出海

当前在各大外资车企不断加码在华投资之际&#xff0c;越来越多的中国汽车品牌纷纷开始走出国门&#xff0c;加速推进全球化业务&#xff0c;将赛道转至更为广阔的海外市场。 上汽海外出行科技有限公司&#xff08;简称“上汽海外出行”&#xff09;成立于2018年&#xff0c;承…

linux高并发web服务器开发(web服务器)18_函数解析http请求, 正则表达式,sscanf使用,http中数据特殊字符编码解码

pdf详情版 01 学习目标 编写函数解析http请求 ○ GET /hello.html HTTP/1.1\r\n ○ 将上述字符串分为三部分解析出来编写函数根据文件后缀&#xff0c;返回对应的文件类型sscanf - 读取格式化的字符串中的数据 ○ 使用正则表达式拆分 ○ [^ ]的用法通过浏览器请求目录数据 ○…

【unity之IMGUI实践】单例模式管理数据存储【二】

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

每日一题——迷宫问题(I)

迷宫问题——I 题目链接 思路 创建二维数组&#xff0c;并实现输入 首先输入二维数组的行和列&#xff1a; int n, m; scanf("%d%d", &n, &m);然后动态开辟二维数组&#xff1a; 注&#xff1a;对动态开辟还不太了解的同学可以看看&#x1f449;C语言—…

CPU密集型和IO密集型任务的权衡:如何找到最佳平衡点

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、CPU密集型与IO密集型3.1、CPU密集型3.2、I/O密…

opencv-15 数字水印原理

最低有效位&#xff08;Least Significant Bit&#xff0c;LSB&#xff09;指的是一个二进制数中的第 0 位&#xff08;即最低位&#xff09;。 最低有效位信息隐藏指的是&#xff0c;将一个需要隐藏的二值图像信息嵌入载体图像的最低有效位&#xff0c;即将载体图像的最低有效…

再开源一款轻量内存池

前两天已开源线程池&#xff0c;开源一款轻量线程池项目&#xff0c;本节继续开源另一个孪生兄弟&#xff1a;内存池。 本节的线程池与内存池代码解析会在我的星球详细讲解。 内存池&#xff1a;https://github.com/Light-City/light-memory-pool 线程池&#xff1a;https://gi…

Python案例分析|使用Python图像处理库Pillow处理图像文件

本案例通过使用Python图像处理库Pillow&#xff0c;帮助大家进一步了解Python的基本概念&#xff1a;模块、对象、方法和函数的使用 使用Python语言解决实际问题时&#xff0c;往往需要使用由第三方开发的开源Python软件库。 本案例使用图像处理库Pillow中的模块、对象来处理…

ZooKeeper原理剖析

1.ZooKeeper简介 ZooKeeper是一个分布式、高可用性的协调服务。在大数据产品中主要提供两个功能&#xff1a; 帮助系统避免单点故障&#xff0c;建立可靠的应用程序。提供分布式协作服务和维护配置信息。 2.ZooKeeper结构 ZooKeeper集群中的节点分为三种角色&#xff1a;Le…

git如何撤销commit(未push)

文章目录 前言undo commitreset current branch to here Undo Commit&#xff0c;Revert Commit&#xff0c;Drop Commit的区别 是否删除对代码的修改是否删除Commit记录是否会新增Commit记录Undo Commit不会未Push会&#xff0c;已Push不会不会Revert Commit会不会会Drop Com…

vue 3.0 如何加载图片

.logo { background: url(~/assets/images/logo.svg) no-repeat center center/contain; width: 117px; height: 24px; margin: 0 20px; } <a class"logo" href"#"></a> 比较实用的书写方式

汽车销售数据可视化分析实战

1、任务 市场需求&#xff1a;各年度汽车总销量及环比&#xff0c;各车类、级别车辆销量及环比 消费能力/价位认知&#xff1a;车辆销售规模及环比、不同价位车销量及环比 企业/品牌竞争&#xff1a;各车系、厂商、品牌车销量及环比&#xff0c;市占率及变化趋势 热销车型&…