文章目录
剑指offer-两个链表的第一个公共节点
题目
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
什么是公共节点
就是两条链表走着走着重合了:
如果没有公共节点返回none就可以了
思路
如果是存在两个链表的,着重考虑一长一短的情况,因为如果都一样长,他们同样的节点肯定都在同样的位置,只需要让指往前走,走到某个时候,两个指针相等就好。但其实这种情况只是两种不一样长度链表的特殊情况而已,这时候可以找到长链表比短链表多了几节,让长链表先走这么几节后,再一起往前走,走到相遇。
- 第一步:边界条件,两个链表某一个不存在(两个链表一模一样,返回链表头即可)
- 第二步:找到长链表比短链表多了几节:方法是连个指针一起走,循环,直到某一个指针为空,然后另一个指针再进入一个循环,同时记录走了几步,得到k。
- 第三步:长链表先走k后,然后一起走,直到相遇
解答
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
# write code here
if pHead1 == pHead2:
return pHead1
# 找到长链表比短链表多了几节
pTmp1 = pHead1
pTmp2 = pHead2
while pTmp1 and pTmp2:
pTmp1 = pTmp1.next
pTmp2 = pTmp2.next
# 如果pTmp2短,那么让pTmp1继续走
if pTmp1:
k = 0
while pTmp1:
pTmp1 = pTmp1.next
k += 1
# 现在长链表比短链表长k,因此先让长链表走k
pTmp1 = pHead1
pTmp2 = pHead2
for i in range(k):
pTmp1 = pTmp1.next
while pTmp1 != pTmp2:
pTmp1 = pTmp1.next
pTmp2 = pTmp2.next
return pTmp1
if pTmp2:
k = 0
while pTmp2:
pTmp2 = pTmp2.next
k += 1
# 现在长链表比短链表长k,因此先让长链表走k
pTmp1 = pHead1
pTmp2 = pHead2
for i in range(k):
pTmp2 = pTmp2.next
while pTmp1 != pTmp2:
pTmp1 = pTmp1.next
pTmp2 = pTmp2.next
return pTmp1
以上代码比较冗长,其实可以将其封装一个函数
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
# write code here
def find_equal(shortPointer, longPointer, shortHead, longHead):
k = 0
while longPointer:
longPointer = longPointer.next
k += 1
longPointer = longHead
shortPointer = shortHead
for i in range(k):
longPointer = longPointer.next
while shortPointer != longPointer:
shortPointer = shortPointer.next
longPointer = longPointer.next
return shortPointer
if pHead1 == pHead2:
return pHead1
pTmp1 = pHead1
pTmp2 = pHead2
while pTmp1 and pTmp2:
pTmp1 = pTmp1.next
pTmp2 = pTmp2.next
if pTmp1:
return find_equal(pTmp2, pTmp1, pHead2, pHead1)
if pTmp2:
return find_equal(pTmp1, pTmp2, pHead1, pHead2)