leetcode 探索 鏈表 相交鏈表

題目

編寫一個程序,找到兩個單鏈表相交的起始節點。

如下面的兩個鏈表:
在這裏插入圖片描述
在節點 c1 開始相交。

示例 1:

輸入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
輸出:Reference of the node with value = 8
輸入解釋:相交節點的值爲 8 (注意,如果兩個鏈表相交則不能爲 0)。從各自的表頭開始算起,鏈表 A 爲 [4,1,8,4,5],鏈表 B 爲 [5,0,1,8,4,5]。在 A 中,相交節點前有 2 個節點;在 B 中,相交節點前有 3 個節點。

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists

分析

有幾種方式,比較容易想到是當然是暴力法了。

  • 第一種方式,暴力法,a不動,b動;a動一下,b動全部。挨個比較O(N2)的解法
  • 第二種方式,hashmap解法,循環一遍a鏈表,將其加入到hashmap裏。然後在循環b鏈表,挨個檢查,是否有在map裏。O(M+N)的時間複雜度,O(N)的空間複雜度。
  • 第三種方式,先行法,A和B相交,其實相交的後半段是一樣長的,不同的就是前半段。那麼如果我們能讓A和B通過移動其中的長的,將其向前先走幾步。如圖中B比A長1個節點,讓B先走一步,然後A和B一塊走,就能一起到達相交節點。如果沒有相交,則走到頭就會發現了。
  • 第四種方式,雙指針法,與上個檢測環的交點類似,如何讓A和B彌補長度上的差距呢?讓A走完再走B的開頭走,B走完再走A的開頭走,這樣A和B的移動步數就都是A+B裏,如果有交點,就會一起到達了。

解法

以下是雙指針解法。第三種的先行法,如果在鏈表有長度時候,將只需要O(N)就能判定,而雙指針其實是O(2N)。

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func getIntersectionNode(headA, headB *ListNode) *ListNode {
    if headA == nil || headB == nil  {
        return nil
    }
    a, b := headA, headB
    for a != b {
        if a == nil {
            a = headB
        } else {
            a = a.Next
        }
        if b == nil {
            b = headA
        } else {
            b = b.Next
        }
    }
    
    return a
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章