劍指offer系列-面試題52. 兩個鏈表的第一個公共節點兩個鏈表的 (python)

1. 題目

輸入兩個鏈表,找出它們的第一個公共節點。

2. 解題思路

詳情見 圖解 雙指針法,浪漫相遇
在這裏插入圖片描述

由於鏈表A和鏈表B長度不一定相同,而二者相交之後的鏈表都是相同的,因此這個題的難點在於A和B並不同步,所以造成無法比較兩個鏈表中的節點是否相同。

2.1 渣渣思路

發現了上面的關鍵點之後,就寫出了3.1的代碼,思路如下:
1)分別遍歷A和B,得到鏈表的長度差diff;
2)讓長的鏈表先走diff步,然後兩個鏈表再同時往下走,這樣兩者就是同步的了,可以進行比較了;
3)返回第一個相同的節點,即第一個交點。

2.2 最佳思路

畫圖更容易理解
兩個指針 p 和 q,分別走A+B 和B+A,總長度是一樣的,所以使得後面p和q是同步走的,就可以進行比較了。
1)p遍歷鏈表A,q遍歷鏈表B;
2)當p遍歷到A的末尾後,再遍歷B;
3)當q遍歷到B的末尾後,再遍歷A;
4)返回第一個交點。

3. 代碼實現

3.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:
        """
        因爲鏈表的後部是一致的,所以A和B鏈表長度的差異,也就是在公共節點之前那部分的長度差異,只要兩個指針能夠同步前進,就能找到公共節點
        難點在於:若兩個鏈表長度不一樣的話,二者不會同時到達第一個公共節點,造成無法比對節點。
        """
        length_a = 0
        length_b = 0

        # 1.遍歷鏈表A,得到鏈表A長度
        temp = headA
        while temp:
            length_a += 1
            temp = temp.next

        # 2.遍歷鏈表B,得到鏈表B長度
        temp = headB
        while temp:
            length_b += 1
            temp = temp.next

        # 3. 消去兩個鏈表的差值,使得同步檢查兩個鏈表
        difference = length_a - length_b

        if length_a > length_b: # 讓headA先走difference步,否則headB先走difference步,使得二者同步
            while difference:
                headA = headA.next
                difference -= 1
        else:
            difference = -1 * difference
            while difference:
                headB = headB.next
                difference -= 1

        while headA:
            if headA == headB:
                return headA
            headA = headA.next
            headB = headB.next

        return

3.2 最優解法

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

        return node1

作者:z1m
鏈接:https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/solution/shuang-zhi-zhen-fa-lang-man-xiang-yu-by-ml-zimingm/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

4. 總結

鏈表中的操作,大致爲一下幾種:

  1. 雙指針(同速走,倍速走,相差k步走);
  2. 創建僞節點;
  3. 改變鏈接,改變元素值;
  4. 消除長度差。

5. 參考文獻

[1] 劍指offer叢書
[2] 劍指Offer——名企面試官精講典型編程題

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