一、题目描述
输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
数据范围: 𝑛≤1000
要求:空间复杂度 𝑂(1),时间复杂度 𝑂(𝑛)
例如,输入{1,2,3},{4,5},{6,7}时,两个无环的单向链表的结构如下图所示:
可以看到它们的第一个公共结点的结点值为6,所以返回结点值为6的结点。
输入描述:
输入分为是3段,第一段是第一个链表的非公共部分,第二段是第二个链表的非公共部分,第三段是第一个链表和第二个链表的公共部分。 后台会将这3个参数组装为两个链表,并将这两个链表对应的头节点传入到函数FindFirstCommonNode里面,用户得到的输入只有pHead1和pHead2。
返回值描述:
返回传入的pHead1和pHead2的第一个公共结点,后台会打印以该节点为头节点的链表。
示例1
输入:{1,2,3},{4,5},{6,7}
返回值:{6,7}
说明:第一个参数{1,2,3}代表是第一个链表非公共部分,第二个参数{4,5}代表是第二个链表非公共部分,最后的{6,7}表示的是2个链表的公共部分 这3个参数最后在后台会组装成为2个两个无环的单链表,且是有公共节点的。
示例2
输入:{1},{2,3},{}
返回值:{}
说明:2个链表没有公共节点 ,返回null,后台打印{}
二、算法思想
用两个指针cur1和cur2分别指向两链表的初始节点,然后让指针1遍历链表1的所有节点;同理指针2也遍历链表2的所有节点。当指针A和指针B都遍历完各自的节点后,开始互换赛道,让指针1去走链表2;而指针2则走链表1。继续遍历,两指针就会在某一个点相遇,这里相遇的原因是两个指针走过的节点数相等,都走了两个链表各自独有的长度+公共的长度。所以这个相遇点就是我们要找的第一个公共节点。如果两链表没有公共节点,两个指针最后都指向None,因此返回None。
三、代码
# 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):
if not pHead1 or not pHead2:
return None
cur1,cur2=pHead1,pHead2
while cur1!=cur2:
if cur1:
cur1=cur1.next
else:#这时cur1走完了自己的节点,所以为空了
cur1=pHead2#让cur1换到另一条链表的起点,然后继续移动
if cur2:
cur2=cur2.next
else:#这时cur2走完了自己的节点,所以为空了
cur2=pHead1#让cur2换到另一条链表的起点,然后继续移动
return cur1 #跳出循环的时候,cur1=cur2了,这时候就是公共的节点,或者None
四、学习笔记
需要注意这个示例:
{ },{ },{1,2,3,4,5}
在这个题设中,在这个示例中pHead1和pHead2不等于None,而是直接指向了公共部分的第一个节点1。