当前位置: 首页 > news >正文

数据结构和算法笔记3:双指针法(快慢指针)

双指针法(快慢指针法)在数组、字符串和链表的操作中是非常常见的,这里结合力扣上的题进行可一下梳理,主要的思路是我们要明确快指针指的是什么,慢指针指的是什么。

1. 移除元素类问题

27. 移除元素

要我们移除目标元素,返回移动后元素的新长度。

  • 快指针:原数组的索引,这里是fast
  • 慢指针:移除后数组的索引,这里是slow

我们循环时一定是快指针遍历整个数组,然后慢指针根据条件移动,如果发现快指针不等于指定的目标元素val:nums[fast] != val,我们对当前的nums[slow]赋值为nums[fast],让后slow自增。

class Solution {
public:int removeElement(vector<int>& nums, int val) {int slow = 0;for (int fast = 0; fast < nums.size(); ++fast){if (nums[fast] != val)nums[slow++] = nums[fast];}return slow;}
};

26. 删除有序数组中的重复项

要我们移除数组重复的元素,返回移动后元素的新长度。

  • 快指针:原数组的索引,这里是fast
  • 慢指针:移除后数组的索引,这里是slow

为了看是否有重复项我们一定是比较nums[fast]nums[fast - 1]看是否相等,如果不相等,说明不重复,我们可以把当前的nums[fast]赋值给nums[slow],并且slow往前移动一位,为了fast-1不越界,fast的遍历应该从1开始,也是遍历整个数组,既然从1开始,slow的初始值也应该是1,因为第一个元素我们认为不需要删除。

class Solution {
public:int removeDuplicates(vector<int>& nums) {int slow = 1;for (int fast = 1; fast < nums.size(); ++fast){if (nums[fast] != nums[fast - 1])nums[slow++] = nums[fast];}return slow;}
};

80. 删除有序数组中的重复项 II

要我们移除数组重复的元素,返回移动后元素的新长度,每个元素最多有2个。

  • 快指针:原数组的索引,这里是fast
  • 慢指针:移除后数组的索引,这里是slow

朴素的思路是判断nums[fast]前后元素是否和nums[fast]一样。

class Solution {
public:int removeDuplicates(vector<int>& nums) {int slow = 1;for (int fast = 1; fast < nums.size(); ++fast){if (fast < nums.size() - 1){if (!(nums[fast] == nums[fast - 1] && nums[fast] == nums[fast + 1]))nums[slow++] = nums[fast];}else{nums[slow++] = nums[fast];//最后一个元素不管重不重复都放进来,因为至少要2个}}return slow;}
};

其实可以不拘泥于26题的写法:

class Solution {
public:int removeDuplicates(vector<int>& nums) {int n = nums.size();if (n <= 2)return n;int slow = 2;for (int fast = 2; fast < n; ++fast){if (nums[slow - 2] != nums[fast])nums[slow++] = nums[fast];}return slow;}
};

移除保留最多k个元素的通用写法:

class Solution {
public:int removeDuplicates(vector<int>& nums) {int n = k;if (nums.size() <= k)return n;int slow = k;for (int fast = k; fast < nums.size(); ++fast){if (nums[slow - k] != nums[fast])nums[slow++] = nums[fast];}return slow;}
};

283.移动零

要我们把零全部移动到最后,一种直观的思路是使用移除元素的方法,把零移除完,然后从这时的slow开始把数组后面的值都赋值为0:

  • 快指针:原数组的索引,这里是fast
  • 慢指针:移除后数组的索引,这里是slow

class Solution {
public:void moveZeroes(vector<int>& nums) {int slow = 0;for (int fast = 0; fast < nums.size(); fast++){if (nums[fast] != 0)nums[slow++] = nums[fast];}for (; slow < nums.size(); slow++){nums[slow] = 0;}}
};

但我们要移动0,其实也可以直接进行位置的调换,每当发现一个nums[fast]的值不为0,我们就调换当前nums[slow]nums[fast]的值(而不是把nums[fast]直接幅值给nums[slow]),然后slow自增:

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

844. 比较含退格的字符串

要我们比较两个字符串(包含退格后)是否等,两个字符串都定义快指针和慢指针

  • 快指针:原数组的索引,这里是sfasttfast
  • 慢指针:退格后数组的索引,这里是sslowtslow

对两个字符串都进行快慢指针,退格的时候slow指针自减,因为我们要用到nums[slow++],slow至少为0,所以在slow为0的时候我们规定不自减。

class Solution {
public:bool backspaceCompare(string s, string t) {int sfast = 0;int sslow = 0;int tfast = 0;int tslow = 0;for (; sfast < s.size(); ++sfast){if (s[sfast] != '#')s[sslow++] = s[sfast];else if (sslow != 0)sslow --;}for (; tfast < t.size(); ++tfast){if (t[tfast] != '#')t[tslow++] = t[tfast];else if (tslow != 0)tslow --;}if (tslow != sslow)return false;else{for (int i = 0; i < tslow; ++i){if (t[i] != s[i])return false;}}return true;}
};

增加元素类题目

1089. 复写零

要我们对输入的数组就地进行上述修改,将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。

  • 快指针:原数组的索引,这里是i
  • 慢指针:复写零新数组的索引,这里是j

按照题目要求如果原数组的元素arr[i]碰到0,新数组的索引arr[j]要额外走一步,直到新数组索引越界走出整个循环.

这时候要注意的是原数组多走了一步,我们需要对原数组和新数组进行一步回退。

然后往回赋值(逆序遍历),循环继续进行的条件是原数组的索引i大于等于0,如果新数组索引j没有越界,就把arr[i]的值赋值给arr[j],如果arr[i]碰到0,我们要判断当前索引j前面能不能再赋值(有没有越界),如果可以就把j自减,并且arr[j]赋值为0,接着索引ij继续自减回退,直到循环结束条件达到,数组也就成功复写了零:

class Solution {
public:void duplicateZeros(vector<int>& arr) {int len = arr.size(); int i = 0;int j = 0;while (j < len){if (arr[i] == 0)j++;i++;j++;}i--;j--;while (i >= 0){if (j < len)arr[j] = arr[i];if (arr[i] == 0 && j - 1 >= 0){j--;arr[j] = 0;}i--;j--;}}
};

相关文章:

数据结构和算法笔记3:双指针法(快慢指针)

双指针法&#xff08;快慢指针法&#xff09;在数组、字符串和链表的操作中是非常常见的&#xff0c;这里结合力扣上的题进行可一下梳理&#xff0c;主要的思路是我们要明确快指针指的是什么&#xff0c;慢指针指的是什么。 1. 移除元素类问题 27. 移除元素 要我们移除目标元…...

股票价格预测 | Python实现Autoformer, FEDformer和PatchTST等模型用于股价预测

文章目录 效果一览文章概述环境描述源码设计效果一览 文章概述 Autoformer、FEDformer和PatchTST是一些用于时间序列预测,包括股价预测的模型。它们都是在Transformer模型的基础上进行了改进和扩展,以更好地适应时间序列数据的特点。 Autoformer:Autoformer是一种自适应Tran…...

Git基础学习_p1

文章目录 一、前言二、Git手册学习2.1 Git介绍&前置知识2.2 Git教程2.2.1 导入新项目2.2.2 做更改2.2.3 Git追踪内容而非文件2.2.4 查看项目历史2.2.5 管理分支&#x1f53a;2.2.6 用Git来协同工作2.2.7 查看历史 三、结尾 一、前言 Git相信大部分从事软件工作的人都听说过…...

4.Redis事务

4.Redis事务 文章目录 4.Redis事务是什么&#xff1f;能干嘛&#xff1f;Redis 事务 VS 数据库事务命令总结 是什么&#xff1f; 可以一次执行多个命令&#xff0c;本质是一组命令的集合。一个事务中的所有命令都会序列化&#xff0c;按顺序地串行化执行而不会被其它命令插入&…...

golang 图片加水印

需求&#xff1a; 1&#xff0c;员工签到图片加水印 2&#xff0c;水印文字需要有半透明的底色&#xff0c;避免水印看不清 3&#xff0c;图片宽设置在600&#xff0c;小于600或者大于600都需要等比例修改图片的高度&#xff0c;保持水印在图片中的大小和位置 4&#xff0c;处理…...

sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set问题解决方案

sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set问题解决方案 当我们使用sudo su切换权限时提示错误&#xff1a; sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set该错误出现原因&#xff1a;是因为/usr/bin/sudo的权限被…...

提升效率:使用注解实现精简而高效的Spring开发

IOC/DI注解开发 1.0 环境准备1.1 注解开发定义bean步骤1:删除原XML配置步骤2:Dao上添加注解步骤3:配置Spring的注解包扫描步骤4&#xff1a;运行程序步骤5:Service上添加注解步骤6:运行程序知识点1:Component等 1.2 纯注解开发模式1.2.1 思路分析1.2.2 实现步骤步骤1:创建配置类…...

全面好用的setting.xml配置

<?xml version"1.0" encoding"UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information…...

八股文打卡day14——计算机网络(14)

面试题&#xff1a;TCP的Keepalive和HTTP的Keep-Alive是一个东西吗&#xff1f; 我的回答&#xff1a; TCP的Keepalive 1.位于TCP/IP模型的传输层。 2.是用来判活的。客户端会向服务器发送一个Keepalive包来判断&#xff0c;这个TCP连接是否还存活着。 HTTP中的Keep-Alive 1.…...

NCNN环境部署及yolov5pt转ncnn模型转换推理

该内容还未完整&#xff0c;笔记内容&#xff0c;持续补充。 〇开发环境版本 vs2022 cmake3.21.1 ncnn20231027发行版 yolov5s v6.2 vunlkan1.2.198.1 Protobuf3.20.0 Opencv3.4.1 一、模型转换 yolov5s v6.2训练的pt模型&#xff0c;直接导出tourchscript&#xff0c…...

selenium模块有哪些用途?

Selenium模块是一个用于Web应用程序测试的模块&#xff0c;具有多种示例用法。以下是一些示例&#xff1a; 1.打开网页并执行一些基本操作&#xff0c;如点击按钮、输入文本等。 定位网页元素并执行操作&#xff0c;例如使用 find_element 方法查找单个元素&#xff0c;使用 f…...

精品Nodejs实现的校园疫情防控管理系统的设计与实现健康打卡

《[含文档PPT源码等]精品Nodejs实现的校园疫情防控管理系统的设计与实现[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 操作系统&#xff1a;Windows 10、Windows 7、Win…...

爬虫工作量由小到大的思维转变---<第三十五章 Scrapy 的scrapyd+Gerapy 部署爬虫项目>

前言: 项目框架没有问题大家布好了的话,接着我们就开始部署scrapy项目(没搭好架子的话,看我上文爬虫工作量由小到大的思维转变---&#xff1c;第三十四章 Scrapy 的部署scrapydGerapy&#xff1e;-CSDN博客) 正文: 1.创建主机: 首先gerapy的架子,就相当于部署服务器上的;所以…...

python测试工具: 实现数据源自动核对

测试业务需要&#xff1a; 现有A系统作为下游数据系统&#xff0c;上游系统有A1,A2,A3... 需要将A1,A2,A3...的数据达到某条件后&#xff08;比如&#xff1a;A1系统销售单提交出库成功&#xff09;自动触发MQ然后再经过数据清洗落到A系统&#xff0c;并将清洗后数据通过特定…...

要学习openfoam,c++需要掌握到什么程度?

要学习openfoam&#xff0c;c需要掌握到什么程度&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「c的资料从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全部无偿共享给大家&…...

web一些实验代码——Servlet请求与响应

实验4&#xff1a;Servlet请求与响应 1、在页面输入学生学号&#xff0c;从数据库中查询学生信息并显示。 &#xff08;1&#xff09;启动MySQL数据库服务&#xff0c;新建数据库&#xff0c;将student.sql文件导入到新建数据库&#xff08;建立表&#xff0c;并插入3条数据&…...

GPT系列概述

OPENAI做的东西 Openai老窝在爱荷华州&#xff0c;微软投资的数据中心 万物皆可GPT下咱们要失业了&#xff1f; 但是世界不仅仅是GPT GPT其实也只是冰山一角&#xff0c;2022年每4天就有一个大型模型问世 GPT历史时刻 GPT-1 带回到2018年的NLP 所有下游任务都需要微调&#x…...

基于遗传算法的集装箱吊装优化,基于遗传算法的集装箱装卸优化

目录 背影 遗传算法的原理及步骤 基本定义 编码方式 适应度函数 运算过程 代码 结果分析 完整代码下载: 基于遗传算法的集装箱吊装优化,基于遗传算法的集装箱装卸优化(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/abc991835105/88674652 背影 …...

postgreSQL单机部署

一、环境准备 架构操作系统IP主机名PG版本端口磁盘空间内存CPUsingle 单机centos7192.168.1.10pgserver01PostgreSQL 14.7543350G4G2 1、官网下载源码包 https://www.postgresql.org/download/2、操作系统参数修改 2.1 sysctl.conf配置 vi /etc/sysctl.conf kernel.sysrq …...

思维逻辑题3

题目1&#xff1a; 如果所有A都是B&#xff0c;且某个对象是B&#xff0c;那么它一定是A吗&#xff1f; 答案&#xff1a;不一定&#xff0c;尽管所有A都是B&#xff0c;但还有其他的对象可能也是B。 题目2&#xff1a; 如果A和B都是真&#xff0c;那么以下哪个选项是真&…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

PH热榜 | 2025-06-08

1. Thiings 标语&#xff1a;一套超过1900个免费AI生成的3D图标集合 介绍&#xff1a;Thiings是一个不断扩展的免费AI生成3D图标库&#xff0c;目前已有超过1900个图标。你可以按照主题浏览&#xff0c;生成自己的图标&#xff0c;或者下载整个图标集。所有图标都可以在个人或…...

【深尚想】TPS54618CQRTERQ1汽车级同步降压转换器电源芯片全面解析

1. 元器件定义与技术特点 TPS54618CQRTERQ1 是德州仪器&#xff08;TI&#xff09;推出的一款 汽车级同步降压转换器&#xff08;DC-DC开关稳压器&#xff09;&#xff0c;属于高性能电源管理芯片。核心特性包括&#xff1a; 输入电压范围&#xff1a;2.95V–6V&#xff0c;输…...

用 FFmpeg 实现 RTMP 推流直播

RTMP&#xff08;Real-Time Messaging Protocol&#xff09; 是直播行业中常用的传输协议。 一般来说&#xff0c;直播服务商会给你&#xff1a; ✅ 一个 RTMP 推流地址&#xff08;你推视频上去&#xff09; ✅ 一个 HLS 或 FLV 拉流地址&#xff08;观众观看用&#xff09;…...

Pandas 可视化集成:数据科学家的高效绘图指南

为什么选择 Pandas 进行数据可视化&#xff1f; 在数据科学和分析领域&#xff0c;可视化是理解数据、发现模式和传达见解的关键步骤。Python 生态系统提供了多种可视化工具&#xff0c;如 Matplotlib、Seaborn、Plotly 等&#xff0c;但 Pandas 内置的可视化功能因其与数据结…...

中科院1区顶刊|IF14+:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点

中科院1区顶刊|IF14&#xff1a;多组学MR联合单细胞时空分析&#xff0c;锁定心血管代谢疾病的免疫治疗新靶点 当下&#xff0c;免疫与代谢性疾病的关联研究已成为生命科学领域的前沿热点。随着研究的深入&#xff0c;我们愈发清晰地认识到免疫系统与代谢系统之间存在着极为复…...

20250609在荣品的PRO-RK3566开发板的Android13下解决串口可以执行命令但是脚本执行命令异常的问题

20250609在荣品的PRO-RK3566开发板的Android13下解决串口可以执行命令但是脚本执行命令异常的问题 2025/6/9 20:54 缘起&#xff0c;为了跨网段推流&#xff0c;千辛万苦配置好了网络参数。 但是命令iptables -t filter -F tetherctrl_FORWARD可以在调试串口/DEBUG口正确执行。…...

【HTML】HTML 与 CSS 基础教程

作为 Java 工程师&#xff0c;掌握 HTML 和 CSS 也是需要的&#xff0c;它能让你高效与前端团队协作、调试页面元素&#xff0c;甚至独立完成简单页面开发。本文将用最简洁的方式带你掌握核心概念。 一、HTML&#xff0c;网页骨架搭建 核心概念&#xff1a;HTML通过标签定义内…...