《劍指offer》47、兩連結串列的首個公共結點
阿新 • • 發佈:2020-12-22
技術標籤: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有助於加強棧的運用的熟練性。