leetcode 160. intersection-of-two-linked-lists 相交鏈表 python3

時間:2020-7-1

題目地址:https://leetcode-cn.com/problems/intersection-of-two-linked-lists/

題目難度:Easy

題目描述:

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

如下面的兩個鏈表:

在節點 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 個節點。

示例 2:

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

示例 3:

輸入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
輸出:null
輸入解釋:從各自的表頭開始算起,鏈表 A 爲 [2,6,4],鏈表 B 爲 [1,5]。由於這兩個鏈表不相交,所以 intersectVal 必須爲 0,而 skipA 和 skipB 可以是任意值。
解釋:這兩個鏈表不相交,因此返回 null。

注意:

如果兩個鏈表沒有交點,返回 null.
在返回結果後,兩個鏈表仍須保持原有的結構。
可假定整個鏈表結構中沒有循環。
程序儘量滿足 O(n) 時間複雜度,且僅用 O(1) 內存。


思路1:雙指針法

年度最浪漫算法 錯的人遲早會走散,而對的人遲早會相逢  我來到你的城市,走過你來時的路

  • 創建兩個指針 pApA 和 pBpB,分別初始化爲鏈表 A 和 B 的頭結點。然後讓它們向後逐結點遍歷。
  • 當 pApA 到達鏈表的尾部時,將它重定位到鏈表 B 的頭結點 (你沒看錯,就是鏈表 B); 類似的,當 pBpB 到達鏈表的尾部時,將它重定位到鏈表 A 的頭結點。

  • 若在某一時刻 pApA 和 pBpB 相遇,則 pApA/pBpB 爲相交結點。

  • 想弄清楚爲什麼這樣可行, 可以考慮以下兩個鏈表: A={1,3,5,7,9,11} 和 B={2,4,9,11},相交於結點 9。 由於 B.length (=4) < A.length (=6),pBpB 比 pApA 少經過 22 個結點,會先到達尾部。將 pBpB 重定向到 A 的頭結點,pApA 重定向到 B 的頭結點後,pBpB 要比 pApA 多走 2 個結點。因此,它們會同時到達交點。

  • 如果兩個鏈表存在相交,它們末尾的結點必然相同。因此當 pApA/pBpB 到達鏈表結尾時,記錄下鏈表 A/B 對應的元素。若最後元素不相同,則兩個鏈表不相交。

簡單的公式表達:

  • 若相交,鏈表A: a+c, 鏈表B : b+c. a+c+b+c = b+c+a+c 。則會在公共處c起點相遇。若不相交,a +b = b+a 。因此相遇處是NULL

代碼段1:通過

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        currA, currB = headA, headB    
        while currA != currB:
            currA = currA.next if currA else headB
            currB = currB.next if currB else headA
        return currA

總結:

  1. 厲害了,太優雅了,替換了java的三目運算符
  2. 這道題應該想到對齊長度再遍歷的,哈哈,放棄了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章