【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这里,例如下面的链表也是有环的:

        【leetcode刷题笔记】Linked List Cycle

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

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

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

【leetcode刷题笔记】Linked List Cycle

假设循环执行了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 }

 

你可能感兴趣的:(LeetCode)