题目描述
输入两个无环的单链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
解题思路
- 如图:对于长短不一致的两个链表pHead1、pHead2,使用双指针temp1=pHead1、temp2=pHead2,同时进行循环遍历,短的链表pHead1必定先走到None,这时让短链表的指针继续从长的链表的头结点开始继续遍历;紧接着当长链表pHead2也走到None时,继续从短链表的头结点继续遍历,这样两个指针所遍历的链表长度相等,即为长链表与短链表的长度之和,遍历直到两个指针的指向相同时,表示当前指针所指向结点为第一个公共结点,返回任意指针指向即可。
- 循环遍历指针往下走,直到有一个指针为空,说明该指针指向链表是短的那个;
知道了短链表,可以计算长短链表的长度差;
如果temp1不为空,temp2为空,短链表是pHead2,计算长链表pHead1走多少步到None,步数即为两个链表的长度差;
此时计算出了k值即为两链表的长度差,这时将两个指针重新指向两链表的首结点,从头开始遍历,这时为了让链表步伐一致,我们让长链表指针先移动k步,然后两个指针同时移动,直到两个指针所指向的结点相同时,说明找到了公共结点,遍历停止;
temp2不为空,temp1为空的情况,说明temp1是短链表与前面一致。
代码示例
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
#
# @param pHead1 ListNode类
# @param pHead2 ListNode类
# @return ListNode类
#
class Solution:
def FindFirstCommonNode(self , pHead1 , pHead2 ):
# write code here
temp1 = pHead1
temp2 = pHead2
while temp1 != temp2:
# temp1不为空,继续走
if temp1:
temp1 = temp1.next
# temp1为空,temp1短,则temp1从pHead2的头接着开始走
else:
temp1 = pHead2
# temp2不为空,继续走
if temp2:
temp2 = temp2.next
# temp2为空,temp2短,则temp2从pHead1的头接着开始走
else:
temp2 = pHead1
return temp1
def FindFirstCommonNod2(self, pHead1, pHead2):
# write code here
temp1 = pHead1
temp2 = pHead2
while temp1 and temp2:
if temp1 == temp2:
return temp1
temp1 = temp1.next
temp2 = temp2.next
temp1 = pHead1
temp2 = pHead2
# 循环遍历指针往下走,直到有一个指针为空,
# 说明该指针指向链表是短的那个
while temp1 and temp2:
# 考虑边界条件,只有一个链表,
# 没有公共结点的情况({},{},{1,2,3,4})
if temp1 == temp2:
return temp1
temp1 = temp1.next
temp2 = temp2.next
# 知道了短链表,可以计算长短链表的长度差
# 如果temp1不为空,temp2为空,短链表是pHead2
# 计算长链表pHead1走多少步到None,步数即为两个链表的长度差
if temp1:
k = 0
temp1 = temp1.next
k += 1
# 此时计算出了k值即为两链表的长度差
# 这时将两个指针重新指向两链表的首结点,从头开始遍历
# 这时为了让链表步伐一致,我们让长链表指针先移动k步,
# 然后两个指针同时移动,直到两个指针所指向的结点相同时,说明找到了公共结点,遍历停止
temp1 = pHead1 # 长
temp2 = pHead2 # 短
for i in range(k):
temp1 = temp1.next
while temp1 != temp2:
temp1 = temp1.next
temp2 = temp2.next
return temp1
# temp2不为空,temp1为空的情况,说明temp1是短链表
if temp2:
k = 0
temp2 = temp2.next
k += 1
temp1 = pHead1
temp2 = pHead2
for i in range(k):
temp2 = temp2.next
while temp1 != temp2:
temp1 = temp1.next
temp2 = temp2.next
return temp1
上述代码可以将if判断条件后的代码块进行封装,然后分别调用
def FindFirstCommonNod2(self, pHead1, pHead2):
# write code here
temp1 = pHead1
temp2 = pHead2
while temp1 and temp2:
if temp1 == temp2:
return temp1
temp1 = temp1.next
temp2 = temp2.next
def findShort(shortPointer, longPointer, shortHead, longHead):
k = 0
while longPointer:
longPointer = longPointer.next
k += 1
shortPointer = shortHead
longPointer = longHead
for i in range(k):
longPointer = longPointer.next
while shortPointer != longPointer:
shortPointer = shortPointer.next
longPointer = longPointer.next
return shortPointer
if temp1:
return findShort(temp2, temp1, pHead2, pHead1)
if temp2:
return findShort(temp1, temp2, pHead1, pHead2)