前面,咱們實現了鏈表的 反轉 操做,本篇來聊聊,如何檢測單鏈表中的環。html
Leetcode 141: Linked List Cycle
有兩種方法來解決這個問題:java
定義一個Map,當循環遍歷Linked List時,依次將Node放入Map中,等到循環到下一輪時,檢查Node是否存在於Map中,若存在則表示有環存在。git
/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public boolean hasCycle(ListNode head) { Map map = new IdentityHashMap(); for(ListNode x = head; x != null;){ if(map.containsKey(x)){ return true; } map.put(x, null); x = x.next; } return false; } }
Floyd判圈算法若是有限狀態機、迭代函數或者鏈表上存在環,那麼在某個環上以不一樣速度前進的2個指針)一定會在某個時刻相遇。同時顯然地,若是從同一個起點(即便這個起點不在某個環上)同時開始以不一樣速度前進的2個指針最終相遇,那麼能夠斷定存在一個環,且能夠求出2者相遇處所在的環的起點與長度。github
從Linked List的Head節點出發,咱們定義兩個移動指針,一個的移動速度爲每次前進一個節點,另外一個每次前進兩個節點。而後判斷這兩個指針移動後的結果是否相等。算法
/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public boolean hasCycle(ListNode head) { ListNode slow = head; ListNode fast = head; while(fast != null && fast.next != null){ slow = slow.next; fast = fast.next.next; if(slow == fast){ return true; } } return false; } }
這兩種方式的時間複雜度均爲O(n),空間複雜度均爲O(1).數據結構