题目描述

一个链表中包含环,如何找出环的入口结点?

思路分析

  1. 判断链表中是否有环:用快慢指针的方法,慢指针走一步,快指针走两步,如果快指针追上了慢指针,就说明有环,而且他们相遇的节点是处于环中的节点
  2. 统计环中节点的个数:利用1中返回的节点,当再次走到该节点时,正好遍历了整个环,从而可以统计出个数n。
  3. 找出入口结点:也是设置两个指针,第一个指针先向后移动n,第二个指针指向头节点,然后同时移动两个指针,它们相遇时的节点就是环的入口节点,(类似于 【链表中倒数第k个结点】 中的思路)

测试用例

  1. 功能测试:链表中包含或者不包含环;链表中有多个或者只有一
    节点。
  2. 特殊输入测试:链表头节点为nullptr指针。

Java代码

public class Offer23 {
public static void main(String[] args) {
test1();
test2();
test3();
test4();
test5();
} public static ListNode EntryNodeOfLoop(ListNode head) {
return Solution1(head);
} /**
* 1.判断链表中是否有环,并找出环中节点个数n 2.将一个指针向前移动n,另个一指针指向头节点 3. 然后同时移动两个指针,两个指针相遇时,就是环的入口
*
* @param head
* @return
*/
private static ListNode Solution1(ListNode head) {
if (head == null) {
return null;
}
// 判断链表中是否有环,并找到快慢指针相遇的节点
ListNode meetNode = MeetingNode(head);
if (meetNode == null) {// 说明链表中没有环
return null;
}
int count = 1; // 统计环中节点的个数
ListNode pLoop = meetNode;
while (pLoop.next != meetNode) {
pLoop = pLoop.next;
++count;
} ListNode p1 = head;
for (int i = 0; i < count; i++) {
p1 = p1.next;
}
ListNode p2 = head;
while (p1 != p2) {
p1 = p1.next;
p2 = p2.next;
} return p1;
} /**
* 设置两个指针,快指针一次走两步,慢指针一次走一步 如果快指针 追上了慢指针,就说明有环
* 如果快指针走到尾部(null)时两个指针没有相遇,就说明两个指针没有环存在,
*
* @param head
* @return
*/
private static ListNode MeetingNode(ListNode head) { if (head == null) {
return null;
}
ListNode pSlow = head.next;
if (pSlow == null) {
return null;
}
ListNode pFast = pSlow.next; while (pSlow != null && pFast != null) {
if (pSlow == pFast) {
return pFast;
}
pSlow = pSlow.next;
pFast = pFast.next;
if (pFast != null) {
pFast = pFast.next;
}
}
return null;
} private static void test1() { ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
ListNode node4 = new ListNode(4);
ListNode node5 = new ListNode(5);
ListNode node6 = new ListNode(6); node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = node6;
node6.next = node3; System.out.println("链表中有环而且有多个节点(>=3)---->");
ListNode entryLoop = EntryNodeOfLoop(node1);
if (entryLoop != null) {
System.out.println(entryLoop.val);
} else {
System.out.println("null");
}
} private static void test2() {
ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
ListNode node4 = new ListNode(4);
ListNode node5 = new ListNode(5);
ListNode node6 = new ListNode(6);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = node6;
System.out.println("链表中没有环---->");
ListNode entryLoop = EntryNodeOfLoop(node1);
if (entryLoop != null) {
System.out.println(entryLoop.val);
} else {
System.out.println("null");
}
} private static void test3() { ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
node1.next = node2;
node2.next = node1; ListNode entryLoop = EntryNodeOfLoop(node1);
System.out.println("链表中有环,只有有两个个节点---->");
if (entryLoop != null) {
System.out.println(entryLoop.val);
} else {
System.out.println("null");
}
} private static void test4() { ListNode node1 = new ListNode(1);
node1.next = node1; ListNode entryLoop = EntryNodeOfLoop(node1);
System.out.println("链表中有环,只有一个节点---->");
if (entryLoop != null) {
System.out.println(entryLoop.val);
} else {
System.out.println("没有环");
}
} private static void test5() {
ListNode entryLoop = EntryNodeOfLoop(null);
System.out.println("传入null---->");
if (entryLoop != null) {
System.out.println(entryLoop.val);
} else {
System.out.println("null");
}
} }

代码链接

剑指Offer代码-Java

【Offer】[23] 【链表中环的入口结点】的更多相关文章

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

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

  2. 【剑指Offer】链表中环的入口结点 解题报告(Python)

    [剑指Offer]链表中环的入口结点 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews ...

  3. 剑指offer:链表中环的入口结点

    题目描述: 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 思路分析: 这道题首先需要判断链表是否存在环,很快就能想到用快慢指针来判断. 由于快慢指针的相遇位置并不一定为链 ...

  4. Go语言实现:【剑指offer】链表中环的入口结点

    ​该题目来源于牛客网<剑指offer>专题. 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. Go语言实现: /** * Definition for sing ...

  5. 剑指Offer 55. 链表中环的入口结点 (链表)

    题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 题目地址 https://www.nowcoder.com/practice/253d2c59ec3e4bc68d ...

  6. [剑指Offer] 55.链表中环的入口结点

    题目描述 一个链表中包含环,请找出该链表的环的入口结点. [思路]根据set集合的不重复,遍历链表时遇到的第一个重复结点就是环的入口结点. /* struct ListNode { int val; ...

  7. 剑指Offer:链表中环的入口节点【23】

    剑指Offer:链表中环的入口节点[23] 题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 题目分析 第一步确定链表中是否包含环,怎么确定呢?我们定义两个指针橙和 ...

  8. 《剑指offer》第二十三题(链表中环的入口结点)

    // 面试题23:链表中环的入口结点 // 题目:一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中, // 环的入口结点是结点3. #include <iostream> ...

  9. 链表中环的入口结点 牛客网 剑指Offer

    链表中环的入口结点 牛客网 剑指Offer 题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. # class ListNode: # def __init__(se ...

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

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

随机推荐

  1. 佳木斯集训Day8

    本来能AK的啊啊啊啊啊,唯一一天可以AK,却被Champion误导了(好吧实际上是我理解有问题) T1我写了俩小时,就是一道数列题,推公式的,可以二分解,我觉得二分麻烦,就直接想O(1)了 #incl ...

  2. 理解MySQL(一)--MySQL介绍

    一.Mysql逻辑架构: 1. 第一层:服务器层的服务,连接\线程处理. 2. 第二层:查询执行引擎,MySQL的核心服务功能,包括查询解析.分析.优化和缓存,所有跨存储引擎的功能都在这一层实现. 3 ...

  3. kafka消息的处理机制(五)

    这一篇我们不在是探讨kafka的使用,前面几篇基本讲解了工作中的使用方式,基本api的使用还需要更深入的去钻研,多使用才会有提高.今天主要是探讨一下kafka的消息复制以及消息处理机制. 1. bro ...

  4. 【原创实践】U大师启动安装windows XP

    1:使用U大师3.0版制作启动U盘,拷贝windows xp或者win7的原版安装iso(zh-hans_windows_xp_professional_with_service_pack_3_x86 ...

  5. 大白话5分钟带你走进人工智能-第35节神经网络之sklearn中的MLP实战(3)

    本节的话我们开始讲解sklearn里面的实战: 先看下代码: from sklearn.neural_network import MLPClassifier X = [[0, 0], [1, 1]] ...

  6. centos7 下面python2 共存python3

    第一步.查看python的版本号以及安装路径: 通过以上的查看可以看到,python默认是指向到python2的,所以这里我们不动它,保持现状态即可. 备注:(因为现在还有很多的系统更新都需要使用到p ...

  7. springboot启动慢解决方法

    jdk的配置文件中,使用securerandom.source设置了熵源: cat /usr/java/jdk1.8.0_121/jre/lib/security/java.security secu ...

  8. app发布当天,用户无法登录

    原因:当用户登录时候有商城用户的触发器存在,它会让商城用户也更新成登录状态. 由于用户量大,导致数据库锁死. 最后解决案:删掉触发器,在app的接口登录程序里,追加商城用户更新成登录的操作. 他案1: ...

  9. pyhton介绍、发展趋势、安装

    pyhton介绍.发展趋势.安装 一.python起源 ​ pyhton的创始人为吉多·范罗苏姆(Gudio van Rossum) (后文简称龟叔) ​ 1. 1989年的圣诞节期间,龟叔为了在阿姆 ...

  10. WebSocket实现数据库更新前台实时显示

    通过一个小实例来实现数据库更新后,推送消息给前台,让前台进行相应操作. 需求 数据库更新之后服务器推送消息给前台,让前台做操作.(数据库的数据不是由服务器写入的) 实现的话说到底都是用轮询,因为数据库 ...