【leedcode.141】判斷鏈表是否有環,遞歸非遞歸三種解法

法一:藉助輔助空間

代碼:

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        a = set() 
        while head:
            
            if head in a:
                return True

            a.add(head)
            head = head.next
        return False


理解: 用一個set數據結構存儲每個節點地址;
           時間複雜度O(n*1):訪問每個節點O(n)+存儲每個節點O(1);
           空間複雜度O(n)

法二: 快慢指針法

代碼:

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        slow = fast = head
        # if not head:  # 沒必要這樣寫可以加入while循環判斷更簡潔
        #     return False

        while fast and fast.next:  # 防止head爲空和出現空指針的next的情況
            slow = slow.next
            fast = fast.next.next
            if slow is fast:
                return True

        return False

理解:
      思路:定義一個快指針和慢指針,每次快指針走2步,慢指針走1步,判斷快指針是否與慢指針重逢
      時間複雜度O(n):
               情況一:鏈表部分成環O(n);
               部分成環時,快指針先於慢指針進入環,慢指針進環時間O(n);當快慢指針都進入環,假設環節點數量爲K,當快慢指針第一次相遇時,快指針至少已經在環內已經比慢指針多走一圈(多走的這一圈是當慢指針進入後開始算的),時間O(k); 綜上,時間複雜度O(k+n),即爲O(n)

               情況二:鏈表完全成環O(n)
               同起點,第一次相遇時,快指針已經在環內已經比慢指針多走一圈;時間複雜度O(n)

   空間複雜度O(1)


法三:遞歸標記法

代碼:

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        if not head:
            return False

        if head == 0xcafebabe:
            return True

        head.val = 0xcafebabe
        return self.hasCycle(head.next)

理解:
        思路:把訪問過的值都進行賦值,如果鏈表完全成環,則必會出現重複值;0xcafebabe=3405691582;至於爲啥用這個我目前沒有查到爲什麼?
        時間複雜度:O(n);訪問O(n)+賦值O(1)
        空間複雜度:O(1)

 

參考:

https://leetcode-cn.com/problems/linked-list-cycle/solution/huan-xing-lian-biao-by-leetcode/

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章