142.Linked List Cycle II---双指针

题目链接

题目大意:141题目的扩展,给出单链表,判断是否有环,如果有环,找出环的开始的结点,如果没有环,返回null。

法一(借鉴):在已经找出单链表环的基础上再找开始结点,要时刻记住这个环不一定是从尾结点到头结点,有可能是中间的某一段。所以对于这里具体路径的分析,有两个博客可看http://blog.csdn.net/xy010902100449/article/details/48995255http://blog.csdn.net/willduan1/article/details/50938210,都是从数学层面去证明方法的可行性,也就是为什么可以在找到相遇点后,再从头开始遍历,第二次相遇点就是开始结点的问题。代码如下(耗时1ms):

 1     public ListNode detectCycle(ListNode head) {
 2         ListNode fast = head;
 3         ListNode slow = head;
 4         while(fast != null && fast.next != null) {
 5             fast = fast.next.next;
 6             slow = slow.next;
 7             if(fast == slow) {
 8                 fast = head;
 9                 while(fast != slow) {
10                     fast = fast.next;
11                     slow = slow.next;
12                 }
13                 return fast;
14             }
15         }
16         return null;
17     }
View Code

法二:利用了141的法二,直接用set存入,如果有相同的则说明肯定是环的开始结点,直接返回即可。此方法的时间复杂度和空间复杂度都挺大的。代码如下(耗时16ms):

 1         Set<ListNode> list = new HashSet<>();
 2         while(head != null) {
 3             if(list.contains(head)) {
 4                 return head;
 5             }
 6             else {
 7                 list.add(head);
 8                 head = head.next;
 9             }
10         }
11         return null;
View Code
原文地址:https://www.cnblogs.com/cing/p/7792679.html