一、题目

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

二、思路

方法一:

  假设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. Django入门与实践-第13章:表单处理(完结)

    http://127.0.0.1:8000/boards/1/ http://127.0.0.1:8000/boards/2/ http://127.0.0.1:8000/boards/3/ http ...

  2. Django入门指南-第8章:第一个测试用例(完结)

    python manage.py test python manage.py test --verbosity=2 # boards/tests.py from django.core.urlreso ...

  3. js继承——扩展Object方式实现继承

    function Parent(name,sex){ this.name = name; this.sex = sex; this.sayName = function(){ console.log( ...

  4. (线段树) Count the Colors --ZOJ --1610

    链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82832#problem/F http://acm.zju.edu.cn/onli ...

  5. hdu 3664 1~n排列(ai>i ) 为k个数

    http://acm.hdu.edu.cn/showproblem.php?pid=3664 求1~n的排列个数,使得逆序数(ai>i ) 为给定的k. dp[i][j]表示前1~i的排列中,有 ...

  6. Java类与类之间的继承关系

    Java父类与子类继承关系,调用的各种关系 示例一(子类调用父类函数): // 定义一类 A public class A { // 此方法打印一句话 public void a() { System ...

  7. 曲演杂坛--HASH的一点理解

    HASH,百度百科上做如下定义: Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列 ...

  8. Alwayson--工作流程

    Alwayson的工作流程: 1. 在主副本上,用户提交数据修改事务,等待服务器返回成功表示: 2. 在主副本上,将事务日志固化(harden),SQL SERVER调用Logwriter线程将事务日 ...

  9. 对Cookie和Session的理解

    本篇文章系自己总结经验,如果有朋友感觉哪里有问题,欢迎留言评论,谢谢~! Cookie和Session的产生背景: 在动态页面里面,每个变量都是有有效期的,所有的变量的最大生命周期就是一个脚本的周期( ...

  10. .net Framework使用之 MongoDB

    新建Helper using MongoDB.Bson; using MongoDB.Driver; using System; using System.Collections.Generic; u ...