【LeetCode 簡單題】35-相交連結串列
阿新 • • 發佈:2018-12-14
宣告:
今天是第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