更多算法题解,请关注公众号《程序员学长》

两个链表的第一个公共结点

问题形容

LeetCode 剑指 Offer 52. 两个链表的第一个公共节点

输出两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。

要求:空间复杂度是O(1),工夫复杂度是O(m+n)。

示例:

剖析问题

这个问题最直观的想法就是遍历链表headA,而后把headA中的所有每个节点都退出到汇合中。而后再循环遍历链表headB,判断结点是否在汇合中,如果在,则返回该结点,该结点就代表第一个公共结点。如果不在,持续遍历,直到完结。如果headB的所有结点都不在汇合中,则表明不相交,间接返回null。

def getIntersectionNode(headA,headB):    nodes=set()    while headA:        nodes.add(headA)        headA=headA.next    while headB:        if nodes.__contains__(headB):            return headB        headB=headB.next    return None

该算法的工夫复杂度是O(m+n),空间复杂度是O(n)。其中m和n别离是链表headA和headB的长度。

因为题目要求工夫复杂度是O(m+n),空间复杂度是O(1)。咱们这里能够应用双指针法将空间复杂度升高到O(1)。咱们别离用两个指针p1和p2别离指向headA和headB,而后同时挪动指针p1和p2。当p1达到headA的开端时,让p1指向headB,当p2达到headB的开端时,让p2指向headA,这样,当它们相遇时,所指的节点就是第一个公共结点。

Tips:假如headA不相交的局部是a,headB不相交的局部是b,公共局部是c,那么headA的长度为a+c,headB的长度为b+c,当a等于b时,能够晓得p1和p2指针同时达到第一个公共结点;当a不等于b时,在p1挪动了a+b+c时,即p1走完headA,又在headB上走了b时,p2也走了a+b+c,即p2走完headB,而后又在headA上走了a,此时p1和p2正好相遇,且指向了第一个公共结点。

def getIntersectionNode(headA,headB):    p1 = headA    p2 = headB    while p1 != p2:        if p1:            p1=p1.next        else:            p1=headB        if p2:            p2=p2.next        else:            p2=headA    return p1

更多算法题解,请关注公众号《程序员学长》