【剑指Offer学习】【面试题56:链表中环的入口结点】
题目:一个链表中包括环。怎样找出环的入口结点?
解题思路
能够用两个指针来解决问题。先定义两个指针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:链表中环的入口结点】的更多相关文章
- 【剑指offer】面试题 23. 链表中环的入口节点
面试题 23. 链表中环的入口节点
- 剑指offer五十五之链表中环的入口结点
一.题目 一个链表中包含环,请找出该链表的环的入口结点. 二.思路 方法一: 假设x为环前面的路程(黑色路程),a为环入口到相遇点的路程(蓝色路程,假设顺时针走), c为环的长度(蓝色+橙色路程). ...
- 剑指Offer(书):链表中环的入口节点
题目:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. public ListNode EntryNodeOfLoop(ListNode pHead) { //第一步,查找是 ...
- (剑指Offer)面试题56:链表中环的入口结点
题目: 一个链表中包含环,请找出该链表的环的入口结点. 思路: 1.哈希表 遍历整个链表,并将链表结点存入哈希表中(这里我们使用容器set),如果遍历到某个链表结点已经在set中,那么该点即为环的入口 ...
- 【剑指offer】面试题 22. 链表中倒数第 K 个节点
面试题 22. 链表中倒数第 K 个节点
- 【剑指offer】面试题 8. 二叉树的下一个结点
面试题 8. 二叉树的下一个结点 NowCoder 题目描述 给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指 ...
- 【剑指Offer】面试题22. 链表中倒数第k个节点
题目 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点.例如,一个链表有6个节点,从头节点开始,它们的值依次是1.2.3.4.5.6. ...
- 《剑指offer》面试题22. 链表中倒数第k个节点
问题描述 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点.例如,一个链表有6个节点,从头节点开始,它们的值依次是1.2.3.4.5. ...
- 《剑指offer》面试题15 链表中的倒数第k个节点 Java版
书中方法:用两个节点一次遍历求得倒数第k个节点.注意头节点为空,k<=0,k大于节点个数的情况. public ListNode find(ListNode head, int k){ if(h ...
- 《剑指offer》面试题56 - I. 数组中数字出现的次数
问题描述 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 示例 1: 输入:nums = [4,1 ...
随机推荐
- PHP输出中文乱码的问题(转)
用echo输出的中文显示成乱码, 其实应该是各种服务器脚本都会遇到这个问题, 根本还是编码问题, 一般来说出于编码兼容考虑大多的页面都将页面字符集定义为utf-8 <meta http-equi ...
- Windows 设置时间同步
1.Windows Server 2008 r2 注:{}内是你要同步的外部服务器地址,例如复旦的时间同步服务器地址为:ntp.fudan.edu.cn,则完整命令如下: w32tm /config ...
- prototype constructor __proto__
constructor, prototype, __proto__ 详解
- 企业管理系统开发笔记(4)---后台登录_MVC过滤器
在asp.net时代,我们通常需要在后台的每个页面进行判断用户是否登录的状态,不管是通过session还是通过windows身份验证还是表单验证方式等等方法来对用户登录进行判断跳转.但是在mvc时代, ...
- HTML滚动条
水平没有滚动条 <body scroll="no" style="overflow-x:hidden"> 垂直没有滚动条 <body scro ...
- js console.log 打印 对像 数组 详解
console.log是什么东西,其实就是一个打印js数组和对像的函数而已,就像是php的print_r,var_dump.console.log这个函数本身没什么好说的,这篇博客告诉大家怎么去用这个 ...
- CentOS下建立本地YUM源并自动更新
1. 尽管有很多的免费镜像提供yum源服务,但是还是有必要建立自己的yum服务器,主要出于以下几点考虑: l 网络速度:访问互联网可能比较慢 l 节省带宽:如果有大量的服务器,架设自己的yum源可以有 ...
- Ubuntu等Linux系统清除DNS缓存的方法
buntu等Linux系统清除DNS缓存的方法 直接说方法: 如果系统下有nscd,那么就直接 sudo /etc/init.d/nscd restart 如果没有也没关系,网上接受的方法大都是 su ...
- Android实现三级联动下拉框 下拉列表spinner
Android实现(省.市.县)三级联动下拉框 下拉列表spinner 转载请注明出处: http://www.goteny.com/articles/2013/11/46.html http://w ...
- 【HDOJ】2585 Hotel
字符串水题. #include <cstdio> #include <cstring> #include <cstdlib> #define MAXN 55 cha ...