[leetcode] Linked List Cycle

今天总结一下用Floyd算法来判断链表中是否有环,如果有环,如何找到环的入口。这一系列问题。

1、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?

分析:第一个题是比较基本的用Floyd算法判断是否有环的问题。大致思想就是定义两个指针,一个每次走一步,一个每次走两步。如果有环,那么肯定会在某个点两者相等。代码如下:
 1 public class Solution {
 2     public boolean hasCycle(ListNode head) {
 3         if ( head == null ) return false;
 4         ListNode tortoise = head;
 5         ListNode hare = head;
 6         while ( hare.next != null && hare.next.next != null ){
 7             hare = hare.next.next;
 8             tortoise = tortoise.next;
 9             if ( hare == tortoise ) return true;
10         }
11         return false;
12     }
13 }

    运行时间0ms,这里要注意刚开始的判断和while循环结束条件,因为hare跑的比tortoise快,所以对于循环结束的判断只要判断hare就行了。


2、Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Note: Do not modify the linked list.

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

分析:第二个题目变成求环的入口问题,还是用Floyd算法。代码如下:
 1 public class Solution {
 2     public ListNode detectCycle(ListNode head) {
 3         if ( head == null || head.next == null || head.next.next == null ) return null;
 4         
 5         ListNode tortoise = head;
 6         ListNode hare = head;
 7         
 8         while ( hare.next != null && hare.next.next != null ){
 9             hare = hare.next.next;
10             tortoise = tortoise.next;
11             if ( hare == tortoise ) break;
12         }
13         if ( hare != tortoise ) return null;
14         
15         ListNode ptr1 = head;
16         ListNode ptr2 = hare;
17         while ( ptr1 != ptr2 ){
18             ptr1 = ptr1.next;
19             ptr2 = ptr2.next;
20         }
21         return ptr1;
22     }
23 }

      运行时间0ms。注意这里要先判断链表个数是否大于三个,因为成环最小要求就是三个。

      Floyd算法思路还是比较清楚的,代码写的过程也比较简单。这里可以再拔高一点,其实Floyd算法就是Two Pointer的应用,两个指针无论在数组还是在链表中用处都非常大。以后会总结相关的题目。

原文地址:https://www.cnblogs.com/boris1221/p/9355848.html