一、题目

  一个链表中包含环,请找出该链表的环的入口结点。

二、思路

方法一:

  假设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五十五之链表中环的入口结点的更多相关文章

  1. 【剑指offer】面试题 23. 链表中环的入口节点

    面试题 23. 链表中环的入口节点

  2. 剑指Offer(书):链表中环的入口节点

    题目:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. public ListNode EntryNodeOfLoop(ListNode pHead) { //第一步,查找是 ...

  3. 剑指offer——面试题23:链表中环的入口节点

    函数: ListNode* MeetingNode(ListNode* pHead) { if(pHead==nullptr) return nullptr; ListNode* quickNode= ...

  4. 剑指offer三十五之数组中的逆序对

    一.题目 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...

  5. 【剑指Offer】56、删除链表中重复的结点

      题目描述:   在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4-> ...

  6. 剑指offer二十五之复杂链表的复制

    一.题目 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...

  7. 剑指offer四十五之扑克牌顺子(序列是否连续)

    一.题目 LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决 ...

  8. 【Java】 剑指offer(23) 链表中环的入口结点

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中, ...

  9. 剑指Offer - 九度1524 - 复杂链表的复制

    剑指Offer - 九度1524 - 复杂链表的复制2014-02-07 01:30 题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点 ...

  10. 剑指Offer - 九度1518 - 反转链表

    剑指Offer - 九度1518 - 反转链表2013-11-30 03:09 题目描述: 输入一个链表,反转链表后,输出链表的所有元素.(hint : 请务必使用链表) 输入: 输入可能包含多个测试 ...

随机推荐

  1. 2081.09.22 Kuma(非旋treap)

    描述 有N张卡片,编号从0到n-1, 刚开始从0到n-1按顺序排好. 现有一个操作, 对于p. l,表示从第p张卡片之后的l张卡片拿到 最前面. 例如n=7的时候, 刚开始卡片序列为0 1 2 3 4 ...

  2. Python调用Google翻译

    出自:http://blog.csdn.net/zhaoyl03/article/details/8830806 最近想动手做一个文档自动下载器,需要模拟浏览器的行为.虽然感觉思路上没有困难,但在技术 ...

  3. Ubuntu在命令行开启远程桌面

    在终端执行下列三个命令即可 gsettings set org.gnome.Vino enabled truegsettings set org.gnome.Vino prompt-enabled f ...

  4. (KMP 模板)Number Sequence -- Hdu -- 1711

    http://acm.hdu.edu.cn/showproblem.php?pid=1711 Number Sequence Time Limit: 10000/5000 MS (Java/Other ...

  5. Java内存模型(一)

    主存储器和工作存储器 Java虚拟机在执行Java程序的过程中会把它管理的内存划分为若干个不同的数据区域,这些区域包括方法区,堆,虚拟机栈,本地方法栈,程序计数器.方法区存储类信息,常量,字节码等数据 ...

  6. 关于Windbg Local kernel debugging for Win7

    在使用Windbg的时候,如果在Win7上使用Kernel Debug时候会弹出下面的对话框: 在这个对话框中所描述的信息中我们可以看到这么一段话: “Local kernel debugging i ...

  7. java web前端easyui(layout+tree+双tabs)布局+树+2个选项卡tabs

    1.列出要实现的样式: 2.实现的代码: 分三大部分: 1):页面主体部分:mian.vm <html> <head> <title>Ks UI</title ...

  8. 集合(三)CopyOnWriteArrayList

    第一次见到CopyOnWriteArrayList,是在研究JDBC的时候,每一个数据库的Driver都是维护在一个CopyOnWriteArrayList中的,为了证明这一点,贴两段代码,第一段在c ...

  9. 打开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 ...

  10. C# 泛型实现Table与实体的相互转换

    public class ModelHandler<T> where T : new() { /// <summary> /// Table转换成实体 /// </sum ...