LeetCode: Linked List Cycle II

先用双指针探到是不是有回环,假设环长为D,head到环的距离(即要找的点到head的距离)为L,慢指针走的距离为L+X,快指针比慢指针快了一个或者多个环,所以为2*(L+X),注意X < D,因为快指针比慢指针多走了一个或者多个环,所以L+X = k*D。这样解得X = k*D - L。这时离环头点距离为D-X = (1-k)*D+L。再来个节点从head开始走,都是慢指针,这样俩个指针会在环头处相遇。因为在环里的那个指针走过的距离为L,这样离环头点距离为L-(1-k)*D+L = (k-1)*D % D = 0。就是环头点。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode *detectCycle(ListNode *head) {
12         ListNode *p, *q;
13         p = q = head;
14         if (!head || !head->next) return NULL;
15         while (q && q->next) {
16             p = p->next;
17             q = q->next->next;
18             if (p == q) break;
19         }
20         if (p != q) return NULL;
21         p = head;
22         while (p != q) {
23             p = p->next;
24             q = q->next;
25         }
26         return p;
27     }
28 };

 C#

 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     public int val;
 5  *     public ListNode next;
 6  *     public ListNode(int x) {
 7  *         val = x;
 8  *         next = null;
 9  *     }
10  * }
11  */
12 public class Solution {
13     public ListNode DetectCycle(ListNode head) {
14         ListNode p = head, q = head;
15         if (head == null || head.next == null) return null;
16         while (q != null && q.next != null) {
17             p = p.next;
18             q = q.next.next;
19             if (p == q) break;
20         }
21         if (p != q) return null;
22         p = head;
23         while (p != q) {
24             p = p.next;
25             q = q.next;
26         }
27         return p;
28     }
29 }
View Code
原文地址:https://www.cnblogs.com/yingzhongwen/p/3426838.html