剑指offer50--链表中环的入口结点
来源:互联网 发布:如何下载pdf软件 编辑:程序博客网 时间:2024/05/18 05:22
一、题目
题目:一个链表中包含环,如何找出环的入口结点
二、举例
比如链表 1->2->3->4->5->6->3,那么链表中是存在环的,且环的入口是3
三、思想
其实该题目的编程并不难,难的是其数学的计算,首先看下面这张图:
1、总体思想:
一开始设置两个指针都指向表头,其中一个每次(一步)前进一个节点的叫p1,另外那个每次(一步)前进两个节点的
叫p2 。p1和p2同时走,当其中有一个遇到null,就证明链表没有环。如何某个时刻(假设走了n步之后),p1和p2指向的地址相
同,那么链表就是有环的。在p1和p2重合后,设置一个p3指向表头,然后p1和p3每次同时行走一步,每步前进一个节点,等到p1
和p3重合时,重合的位置就是环的入口。
2、☆计算公式☆:
(1)Head指的是初始化位置,L1是到链表环入口的长度,L2是整个环的长度,蓝色为重合P1和P2的重合点
(2)入口可重合点处的距离为a,如图所示,p1和p2同时走起,p2比p1块,所以p2在环内可能走了好几圈了
(3)当p1终于走到环里边的时候才能正好重合了
(4)推倒过程如下:
-------------------- L1+a=n #1 //n是p1走过的节点数
-------------------- L1+k*L2+a=2*n #2 //2*n这个是p2走过的节点数,其中的k表示p2可能在环里面走了k圈,k>=1
-------------------- 由#2式减去#1式,有:
-------------------- k*L2 = n #3
-------------------- 同时由#1和#3得到:
-------------------- L1+a = k*L2 #4
-------------------- 接着由#4就得到了如下式:
-------------------- L1 = k*L2 - a = (k-1)*L2 + (L-a)
(5)因为(L-a)表示的是交点与环入口的距离(从交点沿着行走方向到环入口),然后(k-1)是>=0的,因为p2在环中至少绕了一
圈,这样我们就发现:L1的长度 = 环长度的整数倍 + 交点与环入口的距离
☆☆☆☆☆☆☆也就是L1 = L2 - a,所以再让p1或者p2回来往前走L1步就正好重合了☆☆☆☆☆☆☆
四、程序
package 剑指offer;public class Test56 {public static void main(String args[]){ // 1->2->3->4->5 // ^ | // | | // +--+-----+ ListNodeEnter n1 = new ListNodeEnter(1); ListNodeEnter n2 = new ListNodeEnter(2); ListNodeEnter n3 = new ListNodeEnter(3); ListNodeEnter n4 = new ListNodeEnter(4); ListNodeEnter n5 = new ListNodeEnter(5); n1.next = n2; n2.next = n3; n3.next = n4; n4.next = n5; n5.next = n2; System.out.println(findEnterOfList(n1));}public static int findEnterOfList(ListNodeEnter head){//建立两个节点,p1和p2,p1的速度是p2的两倍ListNodeEnter p1 = head;ListNodeEnter p2 = head;while(p1 !=null && p2.next != null){p1 = p1.next.next;p2 = p2.next;if(p1 == p2){break;}}if(p1 == null || p2.next == null){return -1;}//p1重新回到起点p1 = head;while(p1 != p2){p1 = p1.next;p2 = p2.next;}return p1.value;}}class ListNodeEnter{int value;ListNodeEnter next;public ListNodeEnter(int value){this.value = value;}public String toString(){return value+"";}}
--------------output--------------
2
1 0
- 剑指offer50--链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- IEnumerable和IEnumerator
- mysql 常用sql
- rac 中scan vip 是如何做到负载均衡的
- jQuery.html() 函数详解
- 60 进制的研究
- 剑指offer50--链表中环的入口结点
- 跟App相关的辅助类
- 异常:Request processing failed; nested exception is org.apache.ibatis.binding.BindingException
- 智力题1
- 图解HTTPS
- day07_subprocess模块学习
- Idea SpringMVC+Spring+MyBatis+Maven整合
- 尝试深入了解Async-http
- EC---->LRC---->Sparse Erasure Code