剑指offer-面试题23:链表中环的入口节点 快慢指针+双指针
题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。如图所示,节点3是链表中环的入口节点
本题的解决分为两步:(1)确定链表中是否有环(2)如果有环,确定环的入口节点。我们使用双指针法解决此问题
第一步:确定链表中是否有环(快慢指针)
我们使用快慢指针法,它是双指针的一种形式。定义两个指针p1、p2,起始点都在链表的头结点;p1是慢指针每次向前走一步,p2是快指针每次向前走两步;若不存在环,p2会率先到达尾结点的next,即null,此时便可以返回null;若存在环,p2会率先进入环并在环中做循环运动,p1后进入环中,而后p2总会在环中的某一点追上p1;确定有环;
在上图的链表中,p2会在节点5处被p1追上
第二步:确定环的入口节点(双指针法)
这里我们使用上一步的两个指针
要确定环的入口节点,首先要知道环的长度。如上图中的链表,我们从p1、p2相遇的节点5开始,p1再向前走4步会再次回到节点5,由此确定了环的长度为4
已经确定了环的长度n。让p1、p2都回到链表头结点;然后p1不动,p2先向前走n步;接下来p1和p2均一次走一步,直到p1和p2相遇,相遇点就是环的入口点。那么如何证明这一点呢?
证明:
假设链表非环部分长为l,环部分长为n
若l==n,p2先走n=l步到达环的入口;p1走到l步到达环的入口处时p2恰好走n步,绕环一圈回到环的入口与p1相遇
若l<n,p2先走n步,距离环的入口还有l-n;p1走l步到环的入口时,p2也走了l步,因为n+l-n=l,所以此时p2也绕环一圈回到环的入口和p1相遇
若l>n,p2先走n步,已经进入了环n-l步,距离下一次到达环入口还有l步;p1走l步到环的入口时,p2也走l步到达环的入口与p1相遇
因此,当p2先走环的长度步,p1、p2再开始以相同速度前进,p2总会在绕环一周后与p1在环的入口相遇
解题代码:
class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;}
}
public class Solution {public ListNode EntryNodeOfLoop(ListNode pHead){if(pHead==null){return null;}ListNode p1=pHead,p2=pHead;while(p2!=null) //确定是否有环,p1慢指针,p2快指针{p1=p1.next;if(p2.next!=null && p2.next.next!=null){p2=p2.next.next;if(p1==p2) //再次相遇,链表中有环{int lenCircle=1;p2=p2.next;while(p2!=p1) //计算环的长度{p2=p2.next;lenCircle++;}p1=pHead;p2=pHead;for(int i=0;i<lenCircle;i++) //p2向前走环长度的步数{p2=p2.next;}while(p1!=p2){p1=p1.next;p2=p2.next;}break; //p1、p2再次相遇点就是环的入口}}else{return null;}}return p2;}
}
时间复杂度:O(n)
空间复杂度:因为只使用了两个指针,因此是O(1)
剑指offer-面试题23:链表中环的入口节点 快慢指针+双指针相关推荐
- 剑指offer(C++)——链表中环的入口结点
代码如下: struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {} };/*思路:设 ...
- 剑指offer(C++)-JZ23:链表中环的入口结点(数据结构-链表)
作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null. ...
- 剑指offer——面试题23:从上往下打印二叉树
剑指offer--面试题23:从上往下打印二叉树 Solution1: 典型的BFS算法! 思路一开始没想到,按照书上的思路写的答案... 注意:deque是双向队列,在头尾插入都很快! /* str ...
- [剑指offer]面试题23:从上往下打印二叉树
面试题23:从上往下打印二叉树 题目:从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印.例如输入图4.5中的二叉树,则依次打印出8.6.10.5.7.9.11. 二叉树结点的定义如下 ...
- 剑指Offer - 面试题22. 链表中倒数第k个节点(快慢指针)
1. 题目 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点.例如,一个链表有6个节点,从头节点开始,它们的值依次是1.2.3.4.5 ...
- 剑指offer面试题22. 链表中倒数第k个节点(链表)
题目描述 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点.例如,一个链表有6个节点,从头节点开始,它们的值依次是1.2.3.4.5. ...
- 剑指offer面试题[15]-链表中倒数第K个结点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路: 假设链表有n个结点,那么倒数第k个结点就是从头结点开始的第n-k+1个结点,我们只要从头结点开始往后走n-k+1步就可以了.那么问题来了: ...
- 剑指offer面试题23:从上到下打印二叉树(树的层序遍历)
题目:从上往下打印出二叉树的每个节点,同一层的结点按照从左往右的顺序打印. 解题思路:二叉树的层序遍历,在打印一个节点的时候,要把他的子节点保存起来打印第一层要把第二层的节点保存起来, 打印第二层要把 ...
- 剑指offer面试题[23]-从上往下打印二叉树(按层序打印)
题目描述 从上往下打印出二叉树的每个节点,同层节点从左至右打印. /* struct TreeNode {int val;struct TreeNode *left;struct TreeNode * ...
最新文章
- 移动机器人建图与导航代码实现——3.Path Tracking
- msp430编程用什么软件_UG编程是什么?ug编程做什么用的?
- python怎么实现类似#define宏定义_Python系列学习笔记
- python网站后台_Python 网站后台扫描脚本
- MyEclipse Servers视窗出现“Could not create the view: An unexpected exception was thrown”错误解决办法...
- 华为云推UGO:一手抓结构迁移,一手抓SQL转换
- 应该如何设计圣诞元素到项目?
- 【报告分享】2020中国股民图鉴.pdf(附下载链接)
- 蒙特卡洛树搜索_Query 理解和语义召回在知乎搜索中的应用
- VMware vSphere 5.5的12个更新亮点(1)
- 小程序开发——比较好看的登录界面设计
- Linux/centos备份系统镜像工具
- 如何提高抗压能力和适应能力
- 谁是白盒网络市场最大玩家
- linux和aws需要什么配置电脑,AWS EC2云服务器环境配置
- 关于偶的专业-信息工程
- 微信小程序 之wxml保留小数点后两位数的方法及转化为字符串的方法
- 信息技术学考 这题不会做!!
- Linux:如何调整ubuntu的系统界面使其放大
- 编程十年之那些年我见过和用过的RPC