1. 程式人生 > 其它 >《劍指offer》47、兩連結串列的首個公共結點

《劍指offer》47、兩連結串列的首個公共結點

技術標籤:python資料結構連結串列劍指offerpython

offer47的要求很簡單:輸入兩個連結串列,找出它們的第一個公共結點。
又先搬一張圖,最近畫圖很懶啊……

二次遍歷

方法有很多,除了暴力方法外,我最先想到的是二次遍歷:先獲得兩個連結串列的長度,然後在較長的連結串列上先走若干步(兩連結串列長度之差),接著同時在兩個連結串列上遍歷,找到的第一個相同的節點就是他們的第一個公共節點。時間複雜度O(m + n)。

# offer47-solution 1
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2)
: length1 = self.GetLength(pHead1) length2 = self.GetLength(pHead2) if length1 > length2: headLong = pHead1 headShort = pHead2 else: headLong = pHead2 headShort = pHead1 diff = abs(length1 - length2) for
i in range(diff): headLong = headLong.next # 長連結串列的指標先走 while headLong != None and headShort != None and headLong != headShort: # 沒到尾,也沒相同,接著走 headLong = headLong.next headShort = headShort.next return headLong def GetLength(self, pHead): # 先遍歷一次求長度
length = 0 while pHead: pHead = pHead.next length += 1 return length

玄學

以下是一段通過二次遍歷改造的玄學程式碼,請讀者回去自行研究哈哈哈哈哈。

# offer47-solution 2
def FindFirstCommonNode(self, pHead1, pHead2):
    p1, p2 = pHead1, pHead2
    while p1 != p2:
        p1 = p1.next if p1 != None else pHead2
        p2 = p2.next if p2 != None else pHead1
    return p1

輔助棧

輔助棧的方法,見參考連結:
【劍指offer】37. 兩個連結串列的第一個公共節點(python)
同樣是遍歷兩個連結串列,將節點儲存到棧中。然後利用棧先進後出的特點找到公共節點。

# offer47-solution 3
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        # write code here
        while not pHead1 or not pHead2:
            return None
        # 遍歷兩個連結串列,將節點儲存到棧中
        # 然後利用棧先進後出的特點找到公共節點
        stack1 = []
        stack2 = []
        while pHead1:
            stack1.append(pHead1)
            pHead1 = pHead1.next
        while pHead2:
            stack2.append(pHead2)
            pHead2 = pHead2.next
        commonNode = None
        while stack2 and stack1:
            node1 = stack1.pop()
            node2 = stack2.pop()
            if node1 != node2:
                break
            else:
                commonNode = node1
        return commonNode

個人還是覺得常規的二次遍歷好想好寫,但是方法3有助於加強棧的運用的熟練性。