🔥个人主页:@草莓熊Lotso

🎬作者简介:C++研发方向学习者

📖个人专栏:《C++知识分享》《Linux 入门到实践:零基础也能懂》《数据结构与算法》《测试开发实战指南》《算法题闯关指南》

⭐️人生格言:生活是默默的坚持,毅力是永久的享受。

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


目录

 双指针算法介绍:

对撞指针:

快慢指针:

01.移动零

题目链接:

题目描述:

题目示例:

解法:(快排的思想:数组划分区间-数组分两块)

算法思路:

算法流程:

C++代码演示:

算法总结&&笔记展示:

02.复写零

题目链接:

题目描述:

题目示例:

解法:(原地复写-双指针)

算法思路:

算法流程:

C++代码演示:

算法总结&&笔记展示:


 双指针算法介绍:

常见的双指针有两种形式,一种对撞指针,一种是左右指针。

对撞指针:

一般用于顺序结构中,也称左右指针。

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

快慢指针:

又称龟兔赛跑算法,其基本思想就是使用两个移动速度不同的指针在数组或链表等序列结构上移动。

这种方法对于处理环形链表或数组非常有用。其实不单单是环形链表或者数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使用快慢指针的思想。

快慢指针的实现方法有很多种,最常用的一种就是:

  • 在一次循环中,每次让慢的指针向后移动一位,而快的指针往后移动两位,实现一快一慢

01.移动零

【数组分两块】是非常常见的一种题型,主要就是根据一种划分方式,将数组的内容分成左右两部分。这种类型的题,一般就是使用【双指针】来解决。

题目链接:

283. 移动零 - 力扣(LeetCode)

题目描述:

题目示例:

解法:(快排的思想:数组划分区间-数组分两块)

算法思路:

  • 在本题中,我们可以用一个 cur 指针来扫描整个数组,另一个 dest 指针用来记录非零序列的最后一个位置,根据 cur 在扫描的过程中,遇到的不同情况,分类处理,实现数组的划分。
  • cur 遍历期间,使【0,dest】的元素全部都是非零元素,【dest+1,cur-1】的元素全是零

算法流程:

1.初始化 cur=0(用来遍历数组),dest=-1(指向非零元素序列的最后一个位置。因为刚开始我们不知道最后一个非零元素在什么位置,因此初始化为 -1

2.cur 依次往后遍历每个元素,遍历到的元素会有下面两种情况:

   2.1:遇到的元素是 0 ,cur 直接 ++ 。因为我们的目标是让【dest+1,cur-1】内的元素全都是零,因此当 cur  遇到 0 的时候,直接 ++ ,就可以让 0 cur-1 的位置上,从而在【dest+1,cur-1】内;

   2.2:遇到的元素不是 0 dest++,并且交换 cur 位置和 dest 位置的元素,之后让 cur++,扫描下一个元素。

  • 因为 dest 指向的位置是非零元素区间的最后一个位置,如果扫描到一个新的非零元素,那么他的位置应该在 dest+1 的位置上,因此 dest 先自增 1
  • dest++ 之后,指向的元素就是 0 元素(因为非零元素区间末尾的后一个元素就是 0 ),因此可以交换到 cur 所处的位置上,实现 【0,dest】的元素全部都是非零元素,【dest+1,cur-1】的元素全是零。

C++代码演示:

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

算法总结&&笔记展示:

  •   这里用到的方法是我们学习 【快排算法】的时候,【数据划分】过程的重要一步。如果将快排算法拆解的话,这一小段代码就是实现快排算法的【核心步骤】。

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


02.复写零

题目链接:

1089. 复写零 - 力扣(LeetCode)

题目描述:

题目示例:

解法:(原地复写-双指针)

算法思路:

  • 如果【从前往后】进行原地复写操作的话,由于 0 的出现会复写两次,导致没有复写的数【被覆盖掉】。因此我们选择【从后往前】的复写策略。
  • 但是 【从后往前】复写的时候,我们需要找到 【最后一个复写的数】,因此我们的大体流程分两步:1.先找到最后一个复写的数;2.然后从后往前进行复写操作

算法流程:

1.初始化两个指针 cur=0dest=0

2.找到最后一个复写的数:

  • 判断 cur 位置的元素:(1)如果是 0 的话,dest 往后移动两位;(2)否则,dest 往后移动一位
  • 判断 dest 这时候是否已经到结束位置,如果结束就终止循环;
  • 如果没有结束,cur++,继续判断。

3.判断 dest 是否越界到 n 的位置:

如果越界,执行下面三步:

  • n-1 位置的值修改成 0
  • cur 向前移动一步(cur--)
  • dest 向前移动两步(dest -= 2);

4.从 cur 位置开始往前遍历原数组,依次还原出复写后的结果数组:

4.1 判断 cur 位置的值:

  • 如果是 0dest 以及 dest-1 位置修改成 0 dest-=2
  • 如果非零:dest 位置修改成 0dest -= 1

4.2 cur--,复写下一个位置。

C++代码演示:

class Solution {
public:void duplicateZeros(vector<int>& arr) {int cur=0,dest=-1;int n=arr.size();//找到最后一个复写的数while(cur<n){if(arr[cur])dest++;else dest+=2;if(dest>=n-1) break;cur++;}if(dest>=n){arr[n-1]=0;dest-=2;cur--;}while(cur>=0){if(arr[cur]){arr[dest--]=arr[cur];}else{arr[dest--]=0;arr[dest--]=0;}cur--;}}
};

算法总结&&笔记展示:

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


往期回顾:

《吃透 C++ 类和对象(中):拷贝构造函数与赋值运算符重载深度解析》

《吃透 C++ 类和对象(中):const 成员函数与取地址运算符重载解析》

结语:本篇博客系统讲解了双指针算法在数组处理中的应用,重点分析了移动零和复写零两道典型题目。针对移动零问题,采用快排思想实现数组划分;复写零问题则通过前后双指针策略完成原地操作。如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。

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

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

相关文章

【小白笔记】命令不对系统:无法将‘head’项识别为 cmdlet、函数、脚本文件或可运行程序的名称

head : 无法将“head”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保路径正确&#xff0c;然后再试一次。所在位置 行:1 字符: 1 head -5 train_data.csv ~~~~ CategoryInfo : ObjectNotFound: (h…

宋红康 JVM 笔记 Day15|垃圾回收相关算法

一、今日视频区间 P138-P153 二、一句话总结 标记阶段&#xff1a;引用计数算法&#xff1b;标记阶段&#xff1a;可达性分析算法&#xff1b;对象的finalization机制&#xff1b;MAT与JProfiler的GC Roots溯源&#xff1b;清除阶段&#xff1a;标记-清除算法&#xff1b;清除阶…

Go基础(③Cobra)

Cobra 是帮你快速开发命令行工具的框架 假设你想做一个叫 todo 的命令行工具&#xff0c;实现这些功能&#xff1a; todo add "买牛奶" → 添加待办 todo list → 查看所有待办 todo done 1 → 标记第 1 个待办为已完成 没有 Cobra 的话&#xff0c;你需要自己写代…

从 scheduler_tick 到上下文切换:深入解析 Linux 内核的 TIF_NEED_RESCHED 标志设置流程

Linux 是如何决定何时进行上下文切换的&#xff1f; 在Linux中&#xff0c;CPU 上下文切换是指当操作系统将 CPU 从一个进程切换到另一个进程时&#xff0c;保存当前进程的执行状态&#xff0c;并加载新进程的执行状态的过程就称为上下文切换。 但在 Linux 内核中&#xff0c…

Redis 深度解析:数据结构、持久化与集群

Redis (Remote Dictionary Server) 是一种高性能的键值&#xff08;Key-Value&#xff09;内存数据库&#xff0c;以其丰富的数据结构、极低的延迟、出色的稳定性和强大的集群能力&#xff0c;在现代应用程序的开发中扮演着至关重要的角色。无论是作为缓存、消息队列、会话存储…

HTTPS优化简单总结

性能损耗选择椭圆曲线&#xff0c;并生成椭圆曲线的计算耗时CA证书验证的耗时计算pre-master的耗时硬件优化HTTPS是计算密集型任务&#xff0c;不是IO密集型任务所以硬件最好买更高级的CPU&#xff0c;而不是网卡&#xff0c;磁盘协议优化ECDHE代替RSA&#xff0c;因为ECDHE可以…

从IFA再出发:中国制造与海信三筒洗衣机的“答案”

当全球消费电子行业的目光再次聚焦柏林&#xff0c;柏林国际电子消费品展览会(IFA2025)不仅成为创新产品的秀场&#xff0c;更悄然变身为中国企业讲述全球化进阶故事的重要舞台。近日&#xff0c;海信旗下三筒洗衣机——棉花糖Ultra全家筒迎来它的国际首秀&#xff0c;首次海外…

c++工程如何提供http服务接口

在 C 工程里给类似 /index/api/ 的服务&#xff0c;基本步骤如下&#xff1a; 选一个HTTP服务框架&#xff1b;起一条监听线程&#xff08;或线程池&#xff09;&#xff1b;把路径-处理函数注册进去&#xff1b; 下面是 2 种简单的方案。方案 A&#xff1a;Crow&#xff08;He…

cfshow-web入门-php特性

web89 <?php ​ include("flag.php"); highlight_file(__FILE__); ​ if(isset($_GET[num])){$num $_GET[num];if(preg_match("/[0-9]/", $num)){die("no no no!");}if(intval($num)){echo $flag;} } 正则匹配检查不能是数字&#xff0c;但…

ctfshow - web - 命令执行漏洞总结(二)

web73该题目没有开启web72的open_basedir&#xff0c;所以可以使用var_export(scandir(/));exit();进行目录扫描。读取文件函数&#xff1a;require_once()web74scandir()函数被禁用&#xff0c;使用glob://伪协议进行读取根目录文件。cvar_export(glob(../../../*));exit(); c…

如何将视频从安卓手机传输到电脑?

无论你是否是视频爱好者&#xff0c;你可能都希望知道如何将视频从安卓手机传输到电脑&#xff0c;以释放存储空间并防止性能问题。这也有助于同步视频或防止意外删除。在本文中&#xff0c;我们将探索七种高效的传输方法。方法 1&#xff1a;仅通过 USB 将手机视频发送到电脑许…

Pico 4 Enterprise(企业版)与Unity的交互-有线串流调试篇

入手了Pico 4 E做VR开发&#xff0c;谁知入了天坑...根据官方文档&#xff0c;尝试了串流助手、企业串流、PICO Developer Center&#xff0c;陷入了各种版本问题、环境问题的陷阱。而且Pico4E的OS自24年12开始就不再更新&#xff0c;头盔中预装的企业串流版本也较低&#xff0…

redis里多线程的应用具体在哪些场景

Redis 6.0 引入的多线程I/O&#xff0c;​特指用于处理网络数据的读取&#xff08;read&#xff09;和写入&#xff08;write&#xff09;/解析&#xff08;parse&#xff09;的并行化&#xff0c;而绝非将命令的执行&#xff08;真正的数据操作&#xff09;变成多线程。这是一…

DI-GAN:基于深度学习的动态形变多模光纤透反射光控制

DI-GAN:基于深度学习的动态形变多模光纤透反射光控制 1 论文核心概念 本文提出了一种名为 DI-GAN(Deep Imaging Generative Adversarial Network) 的持续深度学习框架,用于动态形变多模光纤(MMF) 的光场控制。该框架能够同时利用透射和反射信息,实现对光纤末端光场的实…

【深度学习新浪潮】具身智能中使用到的世界模型是什么?

在具身智能中,世界模型(World Model) 是智能体对物理环境的内在“认知地图”,它通过学习环境的动态规律(如物体运动、物理交互、因果关系等),实现对未来状态的预测、对过去状态的反推,以及对未观测状态的补全。其核心价值在于:让智能体无需频繁与真实环境交互,就能在…

Qt_UI界面的设计

一、设置UI窗口大小二、接收框只读三、下拉选项双击添加选项1是添加&#xff0c;2是调整顺序四、标签字体居中字体大小五、发送框六、按钮七、透明框&#xff08;可以放标签或图片啥的&#xff09;设置最小宽度八、水平布局九、垂直布局十、弹簧&#xff08;方便给水平垂直布局…

FTP文件传输服务

一、FTP协议、服务器FTP&#xff1a;文件传输协议&#xff08;用于网络文件双向传输的应用层协议&#xff09;特点&#xff1a;最广泛、最底层、较简单&#xff0c;但是明文传输&#xff1b;适用于较大文件的传输1.常见客户端、服务器客户端&#xff1a;WINSCP or filezilla&am…

Nginx运维之路(Docker多段构建新版本并增加第三方模块)

喜大普奔&#xff0c;前两天发现Nginx竟然自带支持了ACME功能&#xff0c;让我很想测试一下&#xff0c;但是发现手头没有资源让我测试&#xff0c;忽然我想到可以用docker来构建nginx然后测试ACME功能&#xff0c;在这个过程中发现原来官方Nginx镜像并没有集成ACME插件&#x…

DrissionPage 优化天猫店铺商品爬虫:现代化网页抓取技术详解

概述在网络数据采集领域&#xff0c;传统的爬虫方法通常面临反爬机制、动态内容加载和效率低下等挑战。本文将以天猫店铺商品爬虫为例&#xff0c;详细介绍如何从传统的 Requests 库迁移到更现代化的 DrissionPage 解决方案&#xff0c;实现更高效、稳定的数据采集。----------…

pytest并发测试,资源问题导致用例失败解决办法

遇见的问题&#xff1a; 测试用例使用thrift资源和redis资源&#xff0c;单独运行case没有问题&#xff0c;但是使用并发pytest-xdist&#xff08;-n 10 和 --distloadscope&#xff09;运行失败原因&#xff1a; 测试用例间存在共享资源竞争&#xff08;如 Redis、Thrift 连接…