File tree 5 files changed +107
-0
lines changed
out/production/LeetCode/nine
5 files changed +107
-0
lines changed Original file line number Diff line number Diff line change
1
+ # linked-list-cycle-ii(找出链表中环的入口节点)
2
+
3
+ <center >知识点:链表</center >
4
+
5
+
6
+ ## 题目描述
7
+ Given a linked list, return the node where the cycle begins. If there is no cycle, returnnull.
8
+
9
+ Follow up:
10
+ Can you solve it without using extra space?
11
+
12
+
13
+ 给定一个链表,返回其中环的入口节点,如果没有环,返回null
14
+ 提示:尽量不要使用额外空间。
15
+
16
+
17
+ ## 解题思路
18
+
19
+ 参考:https://www.nowcoder.com/questionTerminal/6e630519bf86480296d0f1c868d425ad
20
+
21
+ 思路:
22
+
23
+ 1)使用快慢指针方法,判定是否存在环,并记录两指针相遇位置(Z);
24
+
25
+ 2)将两指针分别放在链表头(X)和相遇位置(Z),并改为相同速度推进,则两指针在环开始位置相遇(Y)。
26
+
27
+ 证明如下:
28
+
29
+ 如下图所示,X,Y,Z分别为链表起始位置,环开始位置和两指针相遇位置,则根据快指针速度为慢指针速度的两倍,当两指针相遇时快指针一定比慢指针多走了n圈,可以得出:
30
+
31
+ $2* (a + b) = a + b + n * (b + c)$;
32
+
33
+ 即 $a=(n - 1) * b + n * c = (n - 1)(b + c) +c$;
34
+
35
+ ![ 122270_1439340467801_QQ截图20150812084712] ( https://ws3.sinaimg.cn/large/006tNc79gy1g2238ac663j30ai05a3z0.jpg )
36
+
37
+ 注意到b+c恰好为环的长度,这时如果可以再让快指针走c步(只要是整数圈多c部即可)即可找出入口点了,所以我们再用两个指针,第一个指针p1指向起点X,第二个指针p2指向刚才相遇的点Z,然后让p1和p2一次走一步,当p1走了a步也就是$(n - 1)(b + c) +c$步时,p2也走了$(n - 1)(b + c) +c$步,注意p2起点距离圆的入口点多了b步,那么此时p2应该相对于圆的入口点走了$(n-1)(b+c)+c+b=n(b+c)$步,也就是到了圆的入口点,而p1走了a步自然也到了圆的入口点,所以此时p1与p2会相遇,那么反向推倒,当p1与p2相遇时刚好就在圆的入口点。
38
+
39
+ ## 代码
40
+
41
+ [ 这里] ( ../src/nine/Solution.java )
Original file line number Diff line number Diff line change
1
+ package nine ;
2
+
3
+ /**
4
+ * @author dmrfcoder
5
+ * @date 2019/4/10
6
+ */
7
+
8
+ /**
9
+ * Definition for singly-linked list.
10
+ */
11
+
12
+ class ListNode {
13
+ int val ;
14
+ ListNode next ;
15
+
16
+ ListNode (int x ) {
17
+ val = x ;
18
+ next = null ;
19
+ }
20
+ }
21
+
22
+ public class Solution {
23
+ public ListNode detectCycle (ListNode head ) {
24
+ if (head == null ) {
25
+ return null ;
26
+ }
27
+ ListNode fast , slow ;
28
+ fast = slow = head ;
29
+ while (fast .next != null && fast .next .next != null ) {
30
+ fast = fast .next .next ;
31
+ slow = slow .next ;
32
+ if (fast == slow ) {
33
+ break ;
34
+ }
35
+ }
36
+
37
+ if (fast .next == null || fast .next .next == null ) {
38
+ return null ;
39
+ }
40
+
41
+ fast = head ;
42
+ while (fast != null && slow != null ) {
43
+ if (fast == slow ) {
44
+ return fast ;
45
+ }
46
+ fast = fast .next ;
47
+ slow = slow .next ;
48
+
49
+ }
50
+ return null ;
51
+
52
+
53
+ }
54
+
55
+ public static void main (String [] args ){
56
+ ListNode head =new ListNode (1 );
57
+ ListNode node2 =new ListNode (2 );
58
+ head .next =node2 ;
59
+ node2 .next =head ;
60
+ Solution solution =new Solution ();
61
+ ListNode res =solution .detectCycle (head );
62
+ System .out .println (res .val );
63
+
64
+ }
65
+ }
Original file line number Diff line number Diff line change 150
150
- [ binary-tree-postorder-traversal(后序遍历二叉树)] ( ./LeetCode/Doc/后序遍历二叉树.md )
151
151
- [ binary-tree-preorder-traversal(先序遍历二叉树)] ( ./LeetCode/Doc/先序遍历二叉树.md )
152
152
- [ reorder-list(链表重排序)] ( ./LeetCode/Doc/链表重排序.md )
153
+ - [ linked-list-cycle-ii(找出链表中环的入口节点)] ( ./LeetCode/Doc/找出链表中环的入口节点.md )
153
154
You can’t perform that action at this time.
0 commit comments