數據結構與算法 | Leetcode 141:Linked List Cycle

pexels-photo-589810

前面,咱們實現了鏈表的 反轉 操做,本篇來聊聊,如何檢測單鏈表中的環。html

鏈表環檢測

Leetcode 141: Linked List Cycle

有兩種方法來解決這個問題:java

使用Hashing

思路

定義一個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判圈算法

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).數據結構

參考資料

相關文章
相關標籤/搜索