剑指offer五十五之链表中环的入口结点
一、题目
一个链表中包含环,请找出该链表的环的入口结点。
二、思路
方法一:

假设x为环前面的路程(黑色路程),a为环入口到相遇点的路程(蓝色路程,假设顺时针走), c为环的长度(蓝色+橙色路程)。
定义一个快指针:Sslow=slow.next,一个慢指针:Sfast=fast.next
当快慢指针相遇的时候:
此时慢指针走的路程为Sslow =
x + m * c + a ; 快指针走的路程为Sfast = x + n * c + a,则有:
2 Sslow =
Sfast
2 * ( x + m*c + a ) = (x + n *c + a)
从而可以推导出:
x = (n
- 2 * m )*c - a
= (n - 2 *m -1 )*c + c - a
即环前面的路程 =
数个环的长度(为可能为0) + c - a
什么是c - a?这是相遇点后,环后面部分的路程(橙色路程)。所以,我们可以让一个指针从起点A开始走,让一个指针从相遇点B开始继续往后走,
2个指针速度一样,那么,当从原点的指针走到环入口点的时候(此时刚好走了x),从相遇点开始走的那个指针也一定刚好到达环入口点。所以2者会相遇,且恰好相遇在环的入口点。
最后,判断是否有环,且找环的算法复杂度为:时间复杂度:O(n),空间复杂度:O(1)
方法二:
采用断链法,访问过的节点都断开,最后到达的那个节点一定是循环的入口节点。
三、代码
方法一代码:
/*
public class ListNode {
int val;
ListNode next = null; ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead) {
//检验
if (pHead == null || pHead.next == null || pHead.next.next == null) {
return null;
}
//定义快、慢指针
ListNode fast = pHead.next.next;
ListNode slow = pHead.next; //先判断有没有环
while (fast != slow) {
if (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
} else {
//没有环,返回
return null;
}
} //循环出来的话就是有环,且此时fast==slow,快慢指针在相遇点
fast = pHead;//快指针指向头结点,慢指针在相遇点,
while (fast != slow) { //以相同的速度前进,如果相遇,相遇点则为环的入口
fast = fast.next;
slow = slow.next;
}
//返回环的入口
return slow;
}
}
方法二代码:
/*
下面的是断链法,访问过的节点都断开,最后到达的那个节点一定是循环的入口节点。
*/
public class Solution2 {
public ListNode EntryNodeOfLoop(ListNode pHead) {
if (pHead == null || pHead.next == null) {
return null;
}
ListNode fast = pHead.next;
ListNode slow = pHead;
while (fast != null) {
slow.next = null;
slow = fast;
fast = fast.next;
}
return slow;
}
}
---------------------------------------------
参考链接:
https://www.nowcoder.com/questionTerminal/253d2c59ec3e4bc68da16833f79a38e4
剑指offer五十五之链表中环的入口结点的更多相关文章
- 【剑指offer】面试题 23. 链表中环的入口节点
面试题 23. 链表中环的入口节点
- 剑指Offer(书):链表中环的入口节点
题目:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. public ListNode EntryNodeOfLoop(ListNode pHead) { //第一步,查找是 ...
- 剑指offer——面试题23:链表中环的入口节点
函数: ListNode* MeetingNode(ListNode* pHead) { if(pHead==nullptr) return nullptr; ListNode* quickNode= ...
- 剑指offer三十五之数组中的逆序对
一.题目 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...
- 【剑指Offer】56、删除链表中重复的结点
题目描述: 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4-> ...
- 剑指offer二十五之复杂链表的复制
一.题目 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...
- 剑指offer四十五之扑克牌顺子(序列是否连续)
一.题目 LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决 ...
- 【Java】 剑指offer(23) 链表中环的入口结点
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中, ...
- 剑指Offer - 九度1524 - 复杂链表的复制
剑指Offer - 九度1524 - 复杂链表的复制2014-02-07 01:30 题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点 ...
- 剑指Offer - 九度1518 - 反转链表
剑指Offer - 九度1518 - 反转链表2013-11-30 03:09 题目描述: 输入一个链表,反转链表后,输出链表的所有元素.(hint : 请务必使用链表) 输入: 输入可能包含多个测试 ...
随机推荐
- 2081.09.22 Kuma(非旋treap)
描述 有N张卡片,编号从0到n-1, 刚开始从0到n-1按顺序排好. 现有一个操作, 对于p. l,表示从第p张卡片之后的l张卡片拿到 最前面. 例如n=7的时候, 刚开始卡片序列为0 1 2 3 4 ...
- Python调用Google翻译
出自:http://blog.csdn.net/zhaoyl03/article/details/8830806 最近想动手做一个文档自动下载器,需要模拟浏览器的行为.虽然感觉思路上没有困难,但在技术 ...
- Ubuntu在命令行开启远程桌面
在终端执行下列三个命令即可 gsettings set org.gnome.Vino enabled truegsettings set org.gnome.Vino prompt-enabled f ...
- (KMP 模板)Number Sequence -- Hdu -- 1711
http://acm.hdu.edu.cn/showproblem.php?pid=1711 Number Sequence Time Limit: 10000/5000 MS (Java/Other ...
- Java内存模型(一)
主存储器和工作存储器 Java虚拟机在执行Java程序的过程中会把它管理的内存划分为若干个不同的数据区域,这些区域包括方法区,堆,虚拟机栈,本地方法栈,程序计数器.方法区存储类信息,常量,字节码等数据 ...
- 关于Windbg Local kernel debugging for Win7
在使用Windbg的时候,如果在Win7上使用Kernel Debug时候会弹出下面的对话框: 在这个对话框中所描述的信息中我们可以看到这么一段话: “Local kernel debugging i ...
- java web前端easyui(layout+tree+双tabs)布局+树+2个选项卡tabs
1.列出要实现的样式: 2.实现的代码: 分三大部分: 1):页面主体部分:mian.vm <html> <head> <title>Ks UI</title ...
- 集合(三)CopyOnWriteArrayList
第一次见到CopyOnWriteArrayList,是在研究JDBC的时候,每一个数据库的Driver都是维护在一个CopyOnWriteArrayList中的,为了证明这一点,贴两段代码,第一段在c ...
- 打开AVD时报”Data partition already in use. Changes will not persist!”
错误信息 WARNING: Data partition already in use. Changes will not persist! WARNING: SD Card image alread ...
- C# 泛型实现Table与实体的相互转换
public class ModelHandler<T> where T : new() { /// <summary> /// Table转换成实体 /// </sum ...