1、题目描述:
2、实现思路:
A长度为 a, B长度为b, 假设存在交叉点,此时 A到交叉点距离为 c, 而B到交叉点距离为d后续交叉后长度是一样的,那么就是 a-c = b-d ------> a+d = b+c。
这里意味着只要分别让A和B额外多走一遍B和A,那么必然会走到交叉,注意这里边缘情况是,大家都走到null依然没交叉,那么正好返回null即可。
上述的思路是:指向A的指针curA把A链表走完,然后跳到B链表上走;而同时,指向B的指针curB把B链表走完,然后跳到A链表上走A。这样如果有相交的节点,必然会检查出来,原因看上面的数学公式。
我们发现哪个链表长,那另一个指针就会多走长出来的这一部分(这个时候肯定不会相交,因为都在长的链表上走)。因此,这个解题不就等于:
求出两个链表的长度,并求出两个链表长度的差值,然后让curA移动到,和curB 末尾对齐的位置,如下图:
此时我们就可以比较curA和curB是否相同,如果不相同,同时向后移动curA和curB,如果遇到curA == curB,则找到交点。
3、代码描述(python):
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
curA = headA # 指向A链表
curB = headB # 指向B链表
lenA, lenB = 0, 0 # A, B链表的长度
while curA != None: # 求A链表的长度
lenA += 1
curA = curA.next
while curB != None: # 求B链表的长度
lenB += 1
curB = curB.next
# 此时curA和curB都指向了各自链表的末尾,我们需要重新指向第一个节点
curA = headA
curB = headB
if lenA < lenB: # 让A链表作为最长的链表,这样就不用分情况判断了
lenA, lenB = lenB, lenA
curA, curB = curB, curA
gap = lenA - lenB # 求两个链表的长度差
while gap != 0: # 让curA移动到和curB对齐
curA = curA.next
gap -= 1
while curA != None: # 然后比较curA和curB,若相同则返回这个节点;若比较完都不同,则返回None
if curA == curB:
return curA
curA = curA.next
curB = curB.next
return None