1. 程式人生 > 其它 >Day2 兩個連結串列的第一個公共結點【連結串列】

Day2 兩個連結串列的第一個公共結點【連結串列】

技術標籤:劍指offer

題目:
輸入兩個連結串列,找出它們的第一個公共節點。
leetcode原題連結

思路:
雙指標,p1先遍歷連結串列A,p2先遍歷連結串列B
當p1遍歷完時,回到連結串列B的頭節點
當p2遍歷完時,回到連結串列A的頭節點
直到p1和p2相等,跳出while迴圈

注意:
“公共節點”—>同一節點—>記憶體地址相同。
所以while迴圈的判斷條件是 節點的記憶體地址相同,而非節點的val相等。
如示例1,存在情況:連結串列A和連結串列B都有val為1的節點,但這是兩個獨立的記憶體地址不同的節點,並非公共節點
在這裡插入圖片描述

程式碼:
時間複雜度O(M+N)
空間複雜度O(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:
        p1=headA
        p2=headB
        while p1 != p2:#節點相等,而非val相等
if p1: p1=p1.next else: p1=headB if p2: p2=p2.next else: p2=headA return p1

簡潔寫法

# 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: p1,p2=headA,headB while p1 != p2: p1=p1.next if p1 else headB p2=p2.next if p2 else headA return p1

錯誤程式碼

  1. 預設了連結串列A比連結串列B短。
    -先讓指標p1遍歷連結串列A,直到遍歷完連結串列A時,再讓p1指向連結串列B的頭節點,再對連結串列B的遍歷情況進行判斷。
    -但如果輸入的連結串列B比連結串列A短,while p1下的p2=p2.next語句會報錯Nonetype object has not attribute ‘next’,因為此時p1還未遍歷完A連結串列,p2已經遍歷完B連結串列且p2.next為None,None的型別是Nonetype沒有next方法
    -正確程式碼中是已兩個獨立的if else語句同時進行判斷,無需考慮哪個連結串列更長
  2. 用val相等作為公共節點的判定條件。
    -輸入示例1時,輸出為連結串列B中val為1的節點,而非真公共節點8
    在這裡插入圖片描述
# 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:
        p1=headA
        p2=headB
        while p1:
            p1=p1.next
            p2=p2.next
        p1=headB
        while p2:
            p1=p1.next
            p2=p2.next
        p2=headA
        while p1:
            if p1.val==p2.val:
                return p1
            p1=p1.next
            p2=p2.next
        return None