[路飞]_leetcode刷题_面试题 02.07. 链表相交

405 阅读2分钟

「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

链表相交

题目地址点击

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。 图示两个链表在节点 c1 开始相交:

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。

头脑风暴

其实我一拿到这个题,第一点想的是,想把两个链表反转,然后再遍历两个链表,
找到从哪里开始分叉的,即为相交的点。实际上这个思路是可行的,但是在这一题里,
题目限制了链表必须保持其原始结构,所以放弃。

理论分析

要理解这题的解法,其实明白下面这个图的意思就好了,很简单的小学数学题。

假设两人分别从A、B点出发,以同样的速度跑步,谁点跑到D后,就再从对方的出发点出发,继续跑

问:谁先跑到C点?

解答:
A跑步的路径是(A -> C -> D) + (B -> C)  ,长度为h + n + m
B跑步的路径是(B -> C -> D) + (A -> C)  ,长度为m + n + h
显而易见,两个人跑步的路程是一样的,都是h + n + m。
并且由于两人速度一样,所以一定同时到达C点!!

题解

那么同理,换到我们这道题,用双指针就可以解决

分别在a1点和b1点创建两个指针n1和n2,两个指针一次都一步,
同时往前走,谁点走到c3,谁就从对方出发点继续走,直到两者相等再停下来。

由于有我们上面数学题的理论分析,这种情况,两者一定会相遇。

代码(javascript)

/**
 * @param {ListNode} headA
 * @param {ListNode} headB
 * @return {ListNode}
 */
var getIntersectionNode = function(headA, headB) {
    let PA = headA;
    let PB = headB;
    while(PA != PB){
        //A每次向前都一步,如果A走到头了,那么从B点继续向前走
        PA = PA === null ? headB : PA = PA.next
        //B每次向前都一步,如果B走到头了,那么从A点继续向前走
        PB = PB === null ? headA : PB = PB.next
    }
    return PA
};