【leetcode刷题笔记】Linked List Cycle

Given a linked list, determine if it has a cycle in it.

Follow up:
Can you solve it without using extra space?

解题:开始进入一个误区,跟循环链表搞混了,其实这个环的开头可以不在head这里,例如下面的链表也是有环的:

        

最后是看了讨论才找到方法的。设置一个slow指针,每次往前走一步;设置一个fast指针,每次往前走两步;如果在某个时刻这两个指针重合了,说明链表有环。

下面证明有环两个指针一定相遇:

如图,设从head到环的第一个节点的距离为a,从环的第一个节点到两个指针相遇的节点距离为b,环的长度为k。

假设循环执行了t次,那么slow指针走了t步,指向节点(t-a)%k,fast指针走了2*t步,指向节点(2*t-a)%k,则(t-a)%k=(2*t-a)%k;

解出来t = (n2-n1)*k   (n1,n2为整数,n2>=n1(fast比slow走的快))

所以相遇时间总是有解的,两个指针一定会相遇。

代码:

 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     bool hasCycle(ListNode *head) {
12         ListNode* slow = head;
13         ListNode* fast = head;
14         while(fast != NULL && fast->next != NULL){
15             fast = fast->next->next;
16             slow = slow->next;
17             if(fast == slow)
18                 return true;
19         }
20         return false;
21     }
22 };

 Java版本代码

 1 public class Solution {
 2     public boolean hasCycle(ListNode head) {
 3         if(head == null)
 4             return false;
 5         ListNode fast = head.next;
 6         ListNode slow = head;
 7         while(fast != null && fast.next != null){
 8             if(fast == slow)
 9                 return true;
10             fast = fast.next.next;
11             slow = slow.next;
12         }
13         return false;
14     }
15 }

 

posted @ 2014-04-02 10:37  SunshineAtNoon  阅读(208)  评论(0编辑  收藏  举报