链表经典刷题--快慢指针与双指针
本篇总结链表解题思路----快慢指针,其实也就是双指针,这个快慢并不单纯指“快慢”,它更多的可以表示,速度快慢,距离长度,时间大小等等,用法很有趣也很独特,理解它的思想,是很有必要的。
- 🍭1.链表的中间结点----'速度'
- 🍭2.链表中倒数第k个结点----'距离'
- 🍭3.移除链表元素
🍭1.链表的中间结点----‘速度’
要求返回链表中的中间结点;
当有奇数个结点时,返回中间的结点,当有偶数个结点时,返回第二个中间结点。
传统的思想是遍历链表,算链表长度,然后再找中间值。
但如果只允许遍历一遍链表呢?这种方法就不好使了。
使用快慢指针,轻松解决。
什么叫快慢指针,就是让两个指针都指向链表同时往后走,一个指针每次走两步,称为快指针,一个指针每次走一步,称为慢指针。
当快指针走到尾时,而慢指针所指向的地方就是中间结点。
这种天才想法在后面的许多链表题中都有应用,对解题很棒。
本题需要注意一下奇数个和偶数个结点有什么不同,当结点为偶数时,fast走到了最后一个结点的后面,所以fast成为NULL,当结点为奇数时,fast走到最后一个结点停止,所以fast->next为NULL。所以这个循环的条件就是fast和fast->NULL都不为空时,快慢指针才能往后走。
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* middleNode(struct ListNode* head)
{struct ListNode *fast,*slow;//设置两个指针fast=slow=head;//让快慢指针同时从开头走while(fast!=NULL&&fast->next!=NULL)//当fast不为NULL和fast->next不为空时,才可以正常走,一旦有一个为NULL,则说明两种情况中有一个完成。{slow=slow->next;//慢指针每次走一步fast=fast->next->next;//快指针每次走两步}return slow;//最后不管结点是偶数个还是奇数个,返回值都是慢指针指向的位置}
🍭2.链表中倒数第k个结点----‘距离’
先输入k,要求输出该链表的第k的位置上的结点。
传统思想,遍历链表,算出长度,然后用长度减k再加1即可。
那如果跟上面一样只给你遍历一遍链表那该怎么做呢?
同样方法,快慢指针
只不过这时比较的不是速度了,而是两个指针之间的距离。
我们可以让快指针先走k-1步,然后再让慢指针开始走,当快指针走到最后一个结点时停止,慢指针指向的就是要输出的。
我们还可以让快指针先走k步,然后让慢指针开始走,这时,快慢指针之间的距离就变成了k,当快指针走到最后一个结点时,慢指针其实指向的是前面的结点,而要让慢指针指向后面的结点,让快指针再走一步就可以了。
代码如下:
/*** struct ListNode {* int val;* struct ListNode *next;* };*//*** * @param pListHead ListNode类 * @param k int整型 * @return ListNode类*/
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {// write code herestruct ListNode *fast,*slow;//定义两个指针fast=slow=pListHead;//一开始快慢指针都指向开头if(fast==NULL)//如果链表为空链表则无法返回,返回NULLreturn NULL;int num=k-1;if(k==0)//如果是倒数0个那么也返回NULL{return NULL;}while(num--)//先让快指针走k-1步{if(fast->next==NULL)//我们要确保k的大小不能大于链表的长度对吧,当k的长度大于链表时,就会让链表访问越界,所以先给fast往后走时,要注意不能越界了,如果fast->next为NULL,则表明k是大于链表长度的,之间返回NULL{return NULL;}fast=fast->next;}while(fast->next)//判断结束的条件是当fast->next为NULL时,结束,也就是fast走到最后一个结点时停止,这时快慢指针之间的距离为k-1,而最好一个结点与慢指针所指向的结点的距离就是k-1{slow=slow->next;//慢指针和快指针一起走fast=fast->next;}return slow;//最后返回slow位置即可
}
第二种图解:
/*** struct ListNode {* int val;* struct ListNode *next;* };*//*** * @param pListHead ListNode类 * @param k int整型 * @return ListNode类*/
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {// write code herestruct ListNode *fast,*slow;//定义两个指针fast=slow=pListHead;if(fast==NULL)//当链表为空时,返回NULLreturn NULL;while(k--)//快指针先走k步{//要考虑k如果大于链表本身长度时就非法if(fast==NULL){return NULL;}fast=fast->next;//}while(fast)//这个和快指针先走k-1的结束条件不一样喔,这个结束条件应该是快指针走到最后结点的后面,所以是fast为NULL循环结束{slow=slow->next;//快慢指针一起走fast=fast->next;}return slow;//返回慢指针所在的位置
}
🍭3.移除链表元素
方法1:
我们可以按照传统单链表是如何删除来写。
单链表如何删除呢?
我们要删除这个结点,还要将前面的结点和后面的结点链接起来。这时我们就必须要记录下前面结点的地址了,不然单链表无法再找到前一个结点。
所以我们可以用双指针,一个是进行遍历的指针cur,另一个是用来记录它前面结点的位置的指针prev。
当cur->val!=val时,cur先赋值给prev记录这个位置,然后cur再往后走。
当cur->cal==val时,那么就要将前一个结点链接到后一个结点上。
pre->next=cur->next;
然后释放掉cur。
大体思路是这样,不过还有一些细节问题。
比如如果最后一个元素是要被删的,那么前面一个结点的next就变成野指针了。
所以我们需要将他置为NULL。
还有个问题,如果第一个就是要被删除的结点,那么prev->next就非法,所以要进行讨论
当prev= =NULL时,说明第一个结点就要被删除,相当于头删。
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* removeElements(struct ListNode* head, int val){struct ListNode*cur=head;//cur用来遍历链表,首先指向最前面的
struct ListNode*prev=NULL;//一开始prev为空
while(cur)//利用cur进行遍历
{if(cur->val!=val)//如果不等于{prev=cur;//让prev记录这个位置cur=cur->next;//cur往后走}else//如果等于{if(prev==NULL)//要考虑是否是第一个要删除的,当prev==NULL时,就是删除第一个结点{head=cur->next;//将头结点与第二个结点链接free(cur);//是否curcur=head;//cur往后走,也就是走到第二个结点位置}else{prev->next=cur->next;//将前面的与后面的链接free(cur);//删除中间的cur=prev->next;//cur往后走}}
}
return head;//返回头结点
}
方法2:
我们可以利用数组删除元素的思想来删除链表中的结点
在数组中我们是将不等于val的元素放入一个新的数组。
而在链表里我们也可以这样,当不等于val的结点我们就插入到一个新的链表上去,所以我们还需要创建一个新链表。
我们每次将新结点插入到新链表中时都需要找尾,非常烦人,我们可以定义一个尾指针tail,用来指向新插入结点的地址。
如果cur->val!=val那么就进行尾插,将新结点插入新链表
如果cur->val=val,那么cur 就往后走。
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* removeElements(struct ListNode* head, int val){struct ListNode*cur=head;
struct ListNode*tail=NULL,*newnode=NULL;//创建一个新结点
while(cur)//遍历链表
{if(cur->val!=val)//如果不相同,就把不相同的结点插入到新的链表中{//尾插if(newnode==NULL)//最初新链表肯定为空,可以直接将cur指向的不相同的结点放入到新链表中{newnode=tail=cur;}else{tail->next=cur;//cur所对应的结点插入到tail后面tail=tail->next;//tial要往后走,记录下一个插入结点的位置}cur=cur->next;//cur也要往后走}else{struct ListNode*next=cur->next;//如果元素相同,那先把这个结点的下一个结点地址记录下来free(cur);//释放这个要删除的结点cur=next;//cur往后走}
}if(tail!=NULL)//当tail不为空时,我们需要将tail的next置为NULLtail->next=NULL;
return newnode;
}
相关文章:
链表经典刷题--快慢指针与双指针
本篇总结链表解题思路----快慢指针,其实也就是双指针,这个快慢并不单纯指“快慢”,它更多的可以表示,速度快慢,距离长度,时间大小等等,用法很有趣也很独特,理解它的思想,…...
【Java集合框架】篇四:Set接口
1. Set及主要实现类特点 Set:无序、不可重复(去重)、存储value HashSet:底层使用HashMap,即使用 数组单项链表红黑树 结构进行存储。(jkd8中) LinkedHashSet:是HashSet的子类&…...
Python 数据库连接 + 创建库表+ 插入【内含代码实例】
人生苦短 我用python Python其他实用资料:点击此处跳转文末名片获取 数据库连接 连接数据库前,请先确认以下事项: 您已经创建了数据库 TESTDB.在TESTDB数据库中您已经创建了表 EMPLOYEEEMPLOYEE表字段为 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME。连…...
DSS 部署环境需求清单
文章目录 DSS系统需求项目地址计算资源计算基准:计算引擎程序硬件需求表 :DSS计算及存储资源需求计算资源计算基准:计算程序硬件需求表:DSS系统需求 项目地址 https://github.com/WeBankFinTech/DataSphereStudio 计算资源计算基准: 1.日活用户10万。 2.单用户单日总…...
Python的面向对象,详细讲解Python之用处等基本常识
目录 Python 面向对象 面向对象技术简介 创建类 实例 实例 self代表类的实例,而非类 实例 创建实例对象 访问属性 实例 Python内置类属性 实例 python对象销毁(垃圾回收) 实例 实例 类的继承 实例 方法重写 实例 基础重载方法 运算符重载 实例…...
如何使用固态继电器为恒温器供电
恒温器有两种电源:电池和 24VAC。恒温器需要电池才能不间断地运行。电池消耗的能量尽可能低非常重要,但即使您最大限度地减少消耗,这仍然不是一个用户友好的选择,因为电池会不时需要更换。要降低更换频率,可以使用 24V…...
【LeetCode】剑指 Offer(14)
目录 题目:剑指 Offer 32 - I. 从上到下打印二叉树 - 力扣(Leetcode) 题目的接口: 解题思路: 代码: 过啦!!! 写在最后: 题目:剑指 Offer 32…...
Rman单实例迁移到单实例
关于同平台同版本数据库之间的迁移操作的实验 ---Source DB[rootoracle-db-19cs ~]# cat /etc/redhat-release CentOS Stream release 8 [rootoracle-db-19cs ~]# --- Target DB[rootoracle-db-19ct ~]# cat /etc/redhat-release CentOS Stream release 8 [rootoracle-db-19ct…...
毕业设计 基于stm32舞台彩灯控制器设计app控制系统
基于stm32舞台彩灯控制器设计app控制1、项目简介1.1 系统构成1.2 系统功能2、部分电路设计2.1 STM32F103C8T6核心系统电路设计2.2 WS2812RGB彩灯电路设计3、部分代码展示3.1 控制WS2812显示颜色3.2 设置RGB灯的颜色,角度,亮度实物图1、项目简介 选题指导…...
【MyBatis】篇一.
文章目录1、MyBatis概述2、环境搭建1、MyBatis概述 认识: JavaEE开发的一个套件SSM,即: MyBatis是一个持久层的框架,是对JDBC的一个封装,是一个半自动的ORM框架。 ORM即实体类对象和数据库中的数据的一个映射关系&am…...
【JavaScript速成之路】JavaScript流程控制
📃个人主页:「小杨」的csdn博客 🔥系列专栏:【JavaScript速成之路】 🐳希望大家多多支持🥰一起进步呀! 文章目录前言1,流程控制2,分支结构2.1,if语句2.2&…...
18、基准测试,sysbench
基准测试,sysbench 1. sysbench1.1 用途1.2 安装1.3 版本1.4 查看帮助1.5 测试过程阶段2 CPU 性能测试2.1 测试原理2.2 查看帮助2.3 测试3. 内存性能测试3.1 查看帮助信息3.2 测试过程4.磁盘性能基准测试4.1 查看帮助4.2 生成文件(prepare)4.3 测试文件io(run)4.4 结果分析4.5…...
3D,点云拼接2
文章目录 点云配准方法自动配准技术PCL实现的配准算法两两配准1.关键点提取2.特征描述符3. 对应关系估计4. 对应关系去除5. 变换矩阵估算在上篇文章中对于拼接的概念、拼接精度的评价做了详细的介绍。本文是对拼接(配准)的进一步介绍,涉及更多原理层面的东西。 主要围绕以下三…...
jmeter学习笔记一(http基础知识)
HTTP请求:客户端同通过发送http请求向服务器请求资源的访问。http请求由三部分组成:请求行、请求头、请求正文 请求行包括:请求方法 URI 协议/版本 请求头:Content-type、Cookie、Authorization、User-Agent、Accept、Acc…...
【Java】CompletableFuture 并发顺序调度
前言 Java CompletableFuture 提供了一种异步编程的方式,可以在一个线程中执行长时间的任务,而不会堵塞主线程。 和Future相比,CompletableFuture不仅实现了Future接口,也实现了 CompletionStage接口。Future接口不用多说&#…...
职场人必备的6款实用办公app,每一款都是心头爱
打工人不容易啊,不提高工作效率怕是要被淘汰了。今天给大家分享6款职场人必备的实用办公APP,免费效率神器让工作事半功倍。这些APP每一款都是我的心头爱,肯定会让人大开眼界的,超级实用,直接往下看吧。1、向日葵远程控…...
小丑改造计划之复习一
1.函数重载 根据参数个数 参数顺序 参数类型 的不同 可以在同一个域存在多个同名函数 但是不可以根据返回值 缺省参数的不同去重载函数 2.指针和引用的区别 第一点 指针是内存地址,会开辟内存空间,而引用和它所引用的变量共享同一块内存 第二点 引用必须…...
final修饰符使用中遇到的一些问题
文章目录final修饰符1. final不能用来修饰构造方法2. final修饰变量的一些注意问题2.1 final修饰成员变量2.2 final修饰引用类型2.2.1 演示代码中lombok链式编程介绍final修饰符 final具有“不可改变”的含义,它可以修饰非抽象类、非抽象成员方法和变量。 用final…...
好记又实用的获取电脑型号方法
个人常用的方法 方法二最好记又好用。 方法一 dxdiag命令 按下键盘WINR调出运行在输入框输入dxdiag命令后,按下回车;进入DirectX诊断工具,便可查看系统型号等信息。 这里就会显示系统型号。 方法二 设备和打印机 控制面板-查看方式-小图…...
@Transactional配置详解
一:事务注解Transactional,属性propagation的7个配置 PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。,默认配置,也是常用的选择。 PROPAGATION_SUPPORTS -- 支持当前事务&#…...
性能测试面试题汇总
稳定性测试的怎么挑选的接口? 1、频繁使用的接口:选择那些被频繁使用的接口,因为这些接口可能会面临更大的负载和并发访问,从而可能导致性能问题。 2、核心功能接口:选择那些实现系统核心功能的接口,因为这…...
vue权限控制和动态路由
思路 登录:当用户填写完账号和密码后向服务端验证是否正确,验证通过之后,服务端会返回一个token,拿到token之后(我会将这个token存贮到localStore中,保证刷新页面后能记住用户登录状态)…...
利用正则表达式删掉代码中的所有注释-pycharm为例
首先删除注释 打开您想要删除注释的Python文件。 使用快捷键 Ctrl Shift R 打开 "Replace in Files"(在文件中替换)对话框。 在 "Find"(查找)框中输入以下正则表达式,以查找所有行中的注释内容…...
【java基础】内部类、局部内部类、匿名内部类、静态内部类
内部类 内部类就是定义在另一个类中的类。我们使用内部类的原因主要有以下两点 内部类可以对同一个包中的其他类隐藏内部类方法可以访问定义这个类的作用域中的数据,包括原本私有的数据 public class A {class B {} }我们使用内部类可以访问外部类的所有属性&…...
react renderProps学习记录
react renderProps学习记录1.引入2.改一下呢3.再改一下呢4.总结一下如何向组件内部动态传入带内容的结构(标签)?children propsrender props1.引入 上代码: import React, { Component } from react import ./index.css export default class Parent extends Com…...
关于tf.gather函数batch_dims参数用法的理解
关于tf.gather函数batch_dims参数用法的理解0 前言1. 不考虑batch_dims2. 批处理(考虑batch_dims)2.1 batch_dims12.2 batch_dims02.3 batch_dims>22.4 batch_dims再降为12.5 再将axis降为12.6 batch_dims<02.7 batch_dims总结3. 补充4. 参数和返回值5. 其他相关论述6. 附…...
日常操作linux常用命令
cd /mnt/opt/cqstt/logs/stt-erp docker logs -f --tail1000 stt-erp # 查看物理CPU个数 cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l # 查看每个物理CPU中core的个数(即核数) cat /proc/cpuinfo| grep "cpu cores"| uniq # 查看逻辑CPU的…...
【Java集合框架】篇二:Collection接口方法
JDK不提供此接口的任何直接实现类,而是提供更具体的子接口(如:Set和List)去实现。 Collection 接口是 List和Set接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 集合。方法如下…...
PHP入门指南:简单易学的语法和丰富的调试工具与安全性最佳实践
PHP是一种非常流行的服务器端编程语言,它被广泛地应用于Web开发中。如果您想学习Web开发,那么PHP是一个非常好的选择。在本文中,我将介绍PHP的一些基础知识,包括语法、变量、函数、数组、数据库连接、调试和安全性等。PHP的语法PH…...
前端面试题--HTML篇
一、src和href的区别src指向外部资源的位置,指向的内容会嵌入到文档中当前标签所在的位置;href指向网络资源的位置,建立和当前元素或当前文档之间的链接。二、对HTML语义化的理解根据内容的结构化,选择合适的标签。优点࿱…...
河北怀来县建设局网站/创量广告投放平台
1283: 序列 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 486 Solved: 280[Submit][Status][Discuss]Description 给出一个长度为 的正整数序列Ci,求一个子序列,使得原序列中任意长度为M的子串中被选出的元素不超过K(K,M<100) 个,并…...
汕头市门户网站建设/关键词查询工具有哪些
netstat -ntpl kill -9 PID...
wordpress怎么玩/百度最新版下载
撰文:Chase Devens编辑:南风对传统金融体系的去中介化正在我们眼前重新塑造经济的可能性。自动执行的智能合约允许去中心化金融 (DeFi) 应用比传统的同类应用更快、更高效地提供金融服务。这种开放和可组合的金融环境为有洞察力的开发者创造了机会&#…...
建设小型网站价钱/帮我搜一下长沙做网络销售
16.0.6 现在的置换已经和以前的大不一样了。 1.海洋置换 工具架上的置换,看了一下是出了一个缓存,来存储oceanspectrum的信息, 然后在ocean surface上面 设置好对应的路径,最后直接拿一个面片渲染。 结果(chou…...
抚顺市网站建设/营销网站建设门户
AKCMS是一款PHP的开源CMS。跟大多数的个人网站爱好者一样,我也曾经彷徨于各大开源CMS之间,包括Dedecms,Ecms,Phpcms,动易,乔客,风云等,甚至还曾接触过像一坨屎一样的Supesite&#x…...
关于网站设计与建设的论文/开通网站需要多少钱
比如: 给定学生和成绩: ‘小黑’: 80, ‘小王’: 90, ‘小杨’: 85, ‘小白’: 80 将其按照升序排列输出: 小黑:80 小白:80 小杨:85 小王:90 实现: 方法1:存到一个对象里,对对象的键利用sort排序 let o…...