题目:一个链表中包括环。怎样找出环的入口结点?


解题思路

  能够用两个指针来解决问题。先定义两个指针P1和P2指向链表的头结点。假设链表中环有n个结点,指针P1在链表上向前移动n步,然后两个指针以同样的速度向前移动。

当第二个指针指向环的入口结点时,第一个指针已经环绕着环走了一圈又回到了入口结点。

  剩下的问题就是怎样得到环中结点的数目。我们在面试题15的第二个相关题目时用到了一快一慢的两个指针。

假设两个指针相遇,表明链表中存在环。两个指针相遇的结点一定是在环中。

能够从这个结点出发。一边继续向前移动一边计数,当再次回到这个结点时就能够得到环中结点数了。

结点定义

    private static class ListNode {
private int val;
private ListNode next; public ListNode() {
} public ListNode(int val) {
this.val = val;
} @Override
public String toString() {
return val +"";
}
}

代码实现

public class Test56 {
private static class ListNode {
private int val;
private ListNode next; public ListNode() {
} public ListNode(int val) {
this.val = val;
} @Override
public String toString() {
return val +"";
}
} public static ListNode meetingNode(ListNode head) { ListNode fast = head;
ListNode slow = head; while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
break;
}
} // 链表中没有环
if (fast == null || fast.next == null) {
return null;
} // fast又一次指向第一个结点
fast = head; while (fast != slow) {
fast = fast.next;
slow = slow.next;
} return fast;
} public static void main(String[] args) {
test01();
test02();
test03();
} // 1->2->3->4->5->6
private static void test01() {
ListNode n1 = new ListNode(1);
ListNode n2 = new ListNode(2);
ListNode n3 = new ListNode(3);
ListNode n4 = new ListNode(4);
ListNode n5 = new ListNode(5);
ListNode n6 = new ListNode(6); n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = n6; System.out.println(meetingNode(n1));
} // 1->2->3->4->5->6
// ^ |
// | |
// +--------+
private static void test02() {
ListNode n1 = new ListNode(1);
ListNode n2 = new ListNode(2);
ListNode n3 = new ListNode(3);
ListNode n4 = new ListNode(4);
ListNode n5 = new ListNode(5);
ListNode n6 = new ListNode(6); n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = n6;
n6.next = n3; System.out.println(meetingNode(n1));
} // 1->2->3->4->5->6 <-+
// | |
// +---+
private static void test03() {
ListNode n1 = new ListNode(1);
ListNode n2 = new ListNode(2);
ListNode n3 = new ListNode(3);
ListNode n4 = new ListNode(4);
ListNode n5 = new ListNode(5);
ListNode n6 = new ListNode(6); n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = n6;
n6.next = n6; System.out.println(meetingNode(n1));
}
}

执行结果

【剑指Offer学习】【面试题56:链表中环的入口结点】的更多相关文章

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

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

  2. 剑指offer五十五之链表中环的入口结点

    一.题目 一个链表中包含环,请找出该链表的环的入口结点. 二.思路 方法一: 假设x为环前面的路程(黑色路程),a为环入口到相遇点的路程(蓝色路程,假设顺时针走), c为环的长度(蓝色+橙色路程). ...

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

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

  4. (剑指Offer)面试题56:链表中环的入口结点

    题目: 一个链表中包含环,请找出该链表的环的入口结点. 思路: 1.哈希表 遍历整个链表,并将链表结点存入哈希表中(这里我们使用容器set),如果遍历到某个链表结点已经在set中,那么该点即为环的入口 ...

  5. 【剑指offer】面试题 22. 链表中倒数第 K 个节点

    面试题 22. 链表中倒数第 K 个节点

  6. 【剑指offer】面试题 8. 二叉树的下一个结点

    面试题 8. 二叉树的下一个结点 NowCoder 题目描述 给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指 ...

  7. 【剑指Offer】面试题22. 链表中倒数第k个节点

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

  8. 《剑指offer》面试题22. 链表中倒数第k个节点

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

  9. 《剑指offer》面试题15 链表中的倒数第k个节点 Java版

    书中方法:用两个节点一次遍历求得倒数第k个节点.注意头节点为空,k<=0,k大于节点个数的情况. public ListNode find(ListNode head, int k){ if(h ...

  10. 《剑指offer》面试题56 - I. 数组中数字出现的次数

    问题描述 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 示例 1: 输入:nums = [4,1 ...

随机推荐

  1. 数据类型转换中的一些特殊情况(JY06-JavaScript)

    1.字符串的不可变性 字符串定义了后,会一直占据内存空间,企鹅该处内存空间(栈)不可被重新赋值. 2.短路运算 ||.&& 二元运算符,返回参与运算的操作数的原值(原数据类型和原数据) ...

  2. activiti总结2

    根据流程号查询失败原因. activiti重试机制.齿轮节点.邮件节点.任务节点.ACT_HI_ACTINST历史表.ACT_RU_EXECUTION运行表.看图. 在Eclipse里面自己写个测试方 ...

  3. asp.net微信开发第三篇----自定义会话管理

    和微信用户的沟通少不了,总觉得看起来微信官网后台管理中的会话回复消息有点呆板,所以我这里就自定义了一个会话管理功能,最终效果图如下: 因为我试使用富文本文件CKEDITOR来进行编写,你看到稳中可能会 ...

  4. WCF 接收我服务的 HTTP 响应时发生错误

    错误内容: System.ServiceModel.CommunicationException: 接收对 https://xx.com/xx.svc的 HTTP 响应时发生错误.这可能是由于服务终结 ...

  5. ARGB和RGB

    ARGB 一种色彩模式,也就是RGB色彩模式附加上Alpha(透明度)通道,常见于32位位图的存储结构. ARGB---Alpha,Red,Green,Blue. Alpha-图像通道 如果图形卡具有 ...

  6. linux 第三天11讲

    1.linux下的shell 查看目前使用的是哪种shell env [该命令可以显示当前操作系统的环境变量] env | more chsh -s 输入新的shell 如:/bin/csh shel ...

  7. php访问方法外变量

    class Capture { private static $_CapSite = 222; function dd() { echo self::$_CapSite; } } $cc=new Ca ...

  8. Spring静态属性注入

    今天遇到一个工具类,需要静态注入一个属性,方法如下: 第一步:属性的set和get方法不要加static package cn.com.chinalife.ebusiness.common.util; ...

  9. 托盘图标、气泡以及任务栏崩溃后的自动添加——Shell_NotifyIcon

    托盘图标使用函数 Shell_NotifyIcon 创建.修改和删除,参数主要使用 NOTIFYICONDATA 结构. 任务栏启动时会给所有顶层窗口发送 TaskbarCreated 消息,由于不同 ...

  10. ASP.NET执行cmd命令

    批处理命令,是执行速度最快效益最高的命令.因为批处理命令,说白了,就是ms-dos环境下的命令,有很多的批处理命令,都是纯DOS下的命令. 然而,批处理命令尽管功能强大,却存在不足之处.批处理命令只能 ...