本博客rss订阅地址: http://feed.cnblogs.com/blog/u/147990/rss

LeetCode:Linked List Cycle II

题目:判断单链表是否有环,如果有则找出环的起点。题目链接

这是另一道题的扩展,利用快慢指针判断出是否有环后,还需要找出环的起点,分析如下:

  • 设链表长度为len(链表中非空next指针的个数,下面所说的长度均为非空next指针的个数),链表head到环的起点长度为a,环起点到快慢指针相遇点的长度为b,环的长度为r。
  • 假设到快慢指针相遇时,慢指针移动的长度为s,则快指针移动长度为2s,而快指针移动的长度还等于s加上在环上绕的k圈(k>=1),所以2s=s+kr ,即s = kr。
  • 由s = a + b 和 s = kr 可知 a + b = kr = (k-1)r + r; 而r = len - a,所以a + b = (k-1)r + len - a, 即 a = (k-1)r + len - a - blen - a - b是相遇点到环的起点的长度,由此可知,从链表头到环起点长度 = (k-1)环长度+从相遇点到环起点长度,于是我们从链表头、与相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇点为环起点

代码如下:

 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         // IMPORTANT: Please reset any member data you declared, as
13         // the same Solution instance will be reused for each test case.
14         if(head == NULL || head->next == NULL)return NULL;
15         ListNode *fast = head, *low = head;
16         while(fast != NULL && fast->next != NULL)
17         {
18             low  = low->next;
19             fast = fast->next->next;
20             if(low == fast)break;
21         }
22         if(low == fast)
23         {//寻找环的起点
24             fast = head;
25             while(fast != low)
26             {
27                 fast = fast->next;
28                 low = low->next;
29             }
30             return low;
31         }
32         else return NULL;
33     }
34 };

【版权声明】转载请注明出处:

posted @ 2013-11-10 15:17  tenos  阅读(2045)  评论(0编辑  收藏  举报

本博客rss订阅地址: http://feed.cnblogs.com/blog/u/147990/rss

公益页面-寻找遗失儿童