题目描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出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:链表中环的入口节点 快慢指针+双指针相关推荐

  1. 剑指offer(C++)——链表中环的入口结点

    代码如下: struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {} };/*思路:设 ...

  2. 剑指offer(C++)-JZ23:链表中环的入口结点(数据结构-链表)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null. ...

  3. 剑指offer——面试题23:从上往下打印二叉树

    剑指offer--面试题23:从上往下打印二叉树 Solution1: 典型的BFS算法! 思路一开始没想到,按照书上的思路写的答案... 注意:deque是双向队列,在头尾插入都很快! /* str ...

  4. [剑指offer]面试题23:从上往下打印二叉树

    面试题23:从上往下打印二叉树 题目:从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印.例如输入图4.5中的二叉树,则依次打印出8.6.10.5.7.9.11. 二叉树结点的定义如下 ...

  5. 剑指Offer - 面试题22. 链表中倒数第k个节点(快慢指针)

    1. 题目 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点.例如,一个链表有6个节点,从头节点开始,它们的值依次是1.2.3.4.5 ...

  6. 剑指offer面试题22. 链表中倒数第k个节点(链表)

    题目描述 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点.例如,一个链表有6个节点,从头节点开始,它们的值依次是1.2.3.4.5. ...

  7. 剑指offer面试题[15]-链表中倒数第K个结点

    题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路: 假设链表有n个结点,那么倒数第k个结点就是从头结点开始的第n-k+1个结点,我们只要从头结点开始往后走n-k+1步就可以了.那么问题来了: ...

  8. 剑指offer面试题23:从上到下打印二叉树(树的层序遍历)

    题目:从上往下打印出二叉树的每个节点,同一层的结点按照从左往右的顺序打印. 解题思路:二叉树的层序遍历,在打印一个节点的时候,要把他的子节点保存起来打印第一层要把第二层的节点保存起来, 打印第二层要把 ...

  9. 剑指offer面试题[23]-从上往下打印二叉树(按层序打印)

    题目描述 从上往下打印出二叉树的每个节点,同层节点从左至右打印. /* struct TreeNode {int val;struct TreeNode *left;struct TreeNode * ...

最新文章

  1. 移动机器人建图与导航代码实现——3.Path Tracking
  2. msp430编程用什么软件_UG编程是什么?ug编程做什么用的?
  3. python怎么实现类似#define宏定义_Python系列学习笔记
  4. python网站后台_Python 网站后台扫描脚本
  5. MyEclipse Servers视窗出现“Could not create the view: An unexpected exception was thrown”错误解决办法...
  6. 华为云推UGO:一手抓结构迁移,一手抓SQL转换
  7. 应该如何设计圣诞元素到项目?
  8. 【报告分享】2020中国股民图鉴.pdf(附下载链接)
  9. 蒙特卡洛树搜索_Query 理解和语义召回在知乎搜索中的应用
  10. VMware vSphere 5.5的12个更新亮点(1)
  11. 小程序开发——比较好看的登录界面设计
  12. Linux/centos备份系统镜像工具
  13. 如何提高抗压能力和适应能力
  14. 谁是白盒网络市场最大玩家
  15. linux和aws需要什么配置电脑,AWS EC2云服务器环境配置
  16. 关于偶的专业-信息工程
  17. 微信小程序 之wxml保留小数点后两位数的方法及转化为字符串的方法
  18. 信息技术学考 这题不会做!!
  19. Linux:如何调整ubuntu的系统界面使其放大
  20. 编程十年之那些年我见过和用过的RPC

热门文章

  1. C语言 单词长度 代码
  2. 完整性与完备性的区别
  3. 知乎:月薪2~3万,码农怎样度过一天
  4. PHP 判断字符串长度及字符串切割问题
  5. Golang 多版本管理
  6. (十一:2020.08.28)CVPR 2017 追踪之论文纲要(译)
  7. linux fastQC 操作命令,Linux shell合并fastq测序数据/批量fastqc小脚本|merge|multiqc
  8. 分频器——秒分频、三分频、五分频、任意分频和偶数分频
  9. Matlab simulink中找不到s函数
  10. 租车项目技术点与连接