1. 程式人生 > >LeetCode141——環形連結串列

LeetCode141——環形連結串列

我的LeetCode程式碼倉:https://github.com/617076674/LeetCode

原題連結:https://leetcode-cn.com/problems/linked-list-cycle/description/

題目描述:

知識點:雜湊表、雙指標、連結串列

思路一:用一個hashSet來儲存已經遍歷過的節點

一旦發現某個節點的next節點已經被遍歷過,則說明存在環。

時間複雜度和空間複雜度均是O(n),其中n為連結串列中的節點個數。

JAVA程式碼:

public class Solution1 {
    public boolean hasCycle(ListNode head) {
        HashSet<ListNode> hashSet = new HashSet<>();
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode cur = dummyHead;
        while(null != cur.next){
            if(hashSet.contains(cur.next)){
                return true;
            }
            cur = cur.next;
            hashSet.add(cur);
        }
        return false;
    }
}

LeetCode解題報告:

思路二:用快慢雙指標遍歷連結串列

快指標一次移動兩步,慢指標依次移動一步。將快慢雙指標想象成兩個運動員在賽跑,如果連結串列有環,那麼終有一個時刻快慢雙指標會重合。一旦某個節點的next節點出現null,說明不是環形連結串列。

時間複雜度的分析分為兩種情況:

(1)連結串列中不存在環,顯然其時間複雜度是O(n),其中n是連結串列中的節點個數。

(2)連結串列中不存在環,將慢指標的移動過程劃分為兩個階段:非環部分與環形部分:

a:慢指標在走完非環部分階段後將進入環形部分:此時,快指標已經進入環中,且已經迭代了p次,其中p為非環部分的長度。

b:兩個指標都在環形區域中:考慮兩個在環形賽道上的運動員——快跑者每次移動兩步而慢跑者每次只移動一步。其速度的差值為1,因此需要經過q次迴圈後快跑者可以追上慢跑者,其中q為快跑者與慢跑者之間的距離。這個距離幾乎就是環形部分的長度。

因此,總的時間複雜度依然是O(p + q) = O(n)。空間複雜度是O(1)。

JAVA程式碼:

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode cur1 = dummyHead;
        ListNode cur2 = dummyHead;
        while(true){
            if(null == cur2.next || null == cur2.next.next){
                return false;
            }
            cur1 = cur1.next;
            cur2 = cur2.next.next;
            if(cur1 == cur2){
                return true;
            }
        }
    }
}

LeetCode解題報告: