1. 程式人生 > >【LeetCode 簡單題】35-相交連結串列

【LeetCode 簡單題】35-相交連結串列

宣告:

今天是第35道題。編寫一個程式,找到兩個單鏈表相交的起始節點。以下所有程式碼經過樓主驗證都能在LeetCode上執行成功,程式碼也是借鑑別人的,在文末會附上參考的部落格連結,如果侵犯了博主的相關權益,請聯絡我刪除

(手動比心ღ( ´・ᴗ・` ))

正文

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

例如,下面的兩個連結串列

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

在節點 c1 開始相交。

注意:

  • 如果兩個連結串列沒有交點,返回 null
  • 在返回結果後,兩個連結串列仍須保持原有的結構
  • 可假定整個連結串列結構中沒有迴圈
  • 程式儘量滿足 O(n) 時間複雜度,且僅用 O(1) 記憶體、

解法1。若兩個連結串列不等長,較長的連結串列遍歷完畢後(假設p1指向較長的連結串列),p1重新指向headB,此時p2指向的元素就和p1指向的元素對齊了,想象一下,此時兩連結串列右對齊。在此之後的遍歷就能順利找到相交節點,程式碼如下。

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

class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        # V 1.0,能提交
        p1 = headA
        p2 = headB
        while(p1 != p2):
            p1 = headB if p1 is None else p1.next
            p2 = headA if p2 is None else p2.next
        return p1

解法2。 方法2更好理解一點,就是先把兩個連結串列右對齊(不過這樣相當於假設相交節點在後面,如果在前面就gg了??),但下面的程式碼沒有考慮這點,也能執行成功

class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """        
        # V 2.0,能提交
        # 計算兩個連結串列的長度cnt_A、cnt_B
        p1 = headA
        p2 = headB
        cnt_A = 0
        cnt_B = 0
        while p1 is not None:
            p1 = p1.next
            cnt_A += 1
        while p2 is not None:
            p2 = p2.next
            cnt_B += 1
        
        # p1,p2要重新賦值,因為上述計算長度時兩者已指向None了   
        p1 = headA
        p2 = headB    
        if cnt_A > cnt_B:
            diff = cnt_A - cnt_B    # 讓長度更長的連結串列和更短的連結串列(右)對齊
            while diff>0:
                p1 = p1.next
                diff -= 1
        else:
            diff = cnt_B - cnt_A
            while diff>0:
                p2 = p2.next
                diff -= 1
        while p1 != p2:
            p1 = p1.next
            p2 = p2.next
        return p1

結尾