题目描述
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
公共节点特征:两个链表从该节点开始往后的,对应相同。
1、遍历算法
一个一个挨着对应照
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
# write code here
# O(n^2)
while pHead1 and pHead2:
node = pHead2
while node:
if pHead1 == node:
return pHead1
node = node.next
pHead1 = pHead1.next
return None
时间复杂度O(n2)
2、配合栈结构算法
由于目标是找第一个公共子节点,那么两个链表在该节点之前的节点不相同,而在之后的节点均相同。但如果从前往后比的话,要考虑相等问题和长度问题,而如果从后往前比的话,由于相等部分的长度相同因此,就可以不用考虑长度问题,只考虑相等问题,这就能联想到栈这种先进后出的结构进行实现。
先将两个链表分别存入栈中,再从栈顶元素(链表的表尾)开始弹出,由于为相等部分,因此两个弹出的节点应该为相等,直到弹出到不等部分时,说明已到达第一个公共点的边界,则找到该节点
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
# write code here
stack1 = []
stack2 = []
while pHead1:
stack1.append(pHead1)
pHead1 = pHead1.next
while pHead2:
stack2.append(pHead2)
pHead2 = pHead2.next
node1 = None
while stack1 and stack2 and stack1[-1] is stack2[-1]:
node1 = stack1.pop()
stack2.pop()
return node1
时间复杂度O(n)
3、指针翻转算法
从前往后找的话,需要考虑相等问题和长度问题,若需要解决长度问题就需要搞定两个链表的长度差值,而如果先从头共同遍历两个链表,当某个短的链表先走到头后,再翻转到另一个链表的表头,则此时两个链表指针之间的长度差值,就为链表的长度差值。当两个指针以此位置开始继续遍历时,另一个又走到了头,当它走到头后,再翻转到上一个链表,以此就解决了长度差值问题。
之后就是两个指针一起遍历,当相等时,就位第一个公共点。
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
# write code here
p1 = pHead1
p2 = pHead2
while p1 != p2:
p1 = p1.next if p1 != None else p2
p2 = p2.next if p2 != None else p1
return p1
时间复杂度为O(n)