leecode 探索 鏈表 環形鏈表 II

題目

給定一個鏈表,返回鏈表開始入環的第一個節點。 如果鏈表無環,則返回 null。

爲了表示給定鏈表中的環,我們使用整數 pos 來表示鏈表尾連接到鏈表中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該鏈表中沒有環。
說明:不允許修改給定的鏈表。
示例 1:

輸入:head = [3,2,0,-4], pos = 1
輸出:tail connects to node index 1
解釋:鏈表中有一個環,其尾部連接到第二個節點。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/linked-list-cycle-ii

分析

三種解法

  1. 給ListNode添加count基數,訪問到就+1,如果遇到計數爲2表明被訪問了兩次,就是環的開始。
  2. 雙指針法,快慢指針,快指針走兩步,慢指針走一步,如果有環就會相遇。找到有環之後,新一個指針從頭開始,慢指針繼續向前,畫個圖應該比較明顯的能夠看出,兩人會再同一個點相遇。
  3. 藉助輔助空間O(N),採用一個hashmap,訪問過的加入到hashmap裏,遇到hashmap中已經有的,就表明遇到環了,

解法

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */



func detectCycle(head *ListNode) *ListNode {
    if head == nil || head.Next == nil {
        return nil
    }

    slow, fast := head, head.Next
    for slow != fast {
        if fast == nil || fast.Next == nil {
            return nil
        }
        slow = slow.Next
        fast = fast.Next.Next
    }

    // fmt.Printf("有環\n")
    // 探測到有環了,放慢腳步
    // aNew 站在0位置了,而slow則站在了-1位置
    slow = slow.Next
    for aNew := head; aNew != slow; aNew, slow = aNew.Next, slow.Next {
        // fmt.Printf("1: %v, 2: %v\n", aNew.Val, slow.Val)
    }

    return slow
}
  • 解法2
unc detectCycle(head *ListNode) *ListNode {
    var mm = make(map[*ListNode]bool)
    cur := head
    for cur != nil {
        if _, ok := mm[cur]; ok {
            return cur
        }
        mm[cur] = true
        cur = cur.Next
    }
    return nil
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章