题目描述
题干:
输入两个链表,找出它们的第一个公共节点。
示例1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 8
输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
示例2:
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Reference of the node with value = 2
输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
示例3:
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
解释:这两个链表不相交,因此返回 null。
题解思路
找到两个链表的第一个公共节点,也没有说这个链表的其他信息,这样就需要根据示例观察了
观察所有的示例,他给出的链表都是只有一个相交处,这就让我想到了另一个经典的链表问题
如何判断一个链表是否有环,我们可以用快慢双指针的方法,当快的指针追赶上慢的指针的话就说明有环
这里我们需要的是首个公共节点,我们也可以采用类似的方法,但是就不能快慢指针了,我们需要相同的速度的指针
因为如果他们相交的话,两个链表的和是定长的,抛去相交后的部分,其他部分还是定长的
所以我们规定两个同速指针从两个链表头开始,然后便利完一遍之后交替便利
则如果存在公共点,那么他们就一定会在公共点相遇,这是放回当前节点的值就是我们想要的值
正确代码
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
ListNode pA = headA, pB = headB;
while (pA != pB) {
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pA;
}
总结
链表这个结构天生就是适用于指针这个结构的,而且双指针yyds,总是复杂度最优的解
如果文章存在问题或者有更好的题解,欢迎在评论区斧正和评论,各自努力,你我最高处见