原题链接
力扣https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/
题目描述
输入两个链表,找出它们的第一个公共节点。
示例
输入: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 个节点。
解题思路
- 先判断两个链表是否为空,为空则直接返回空(无相交)。
- 如果均不为空,让两个链表分别从头跑到尾,并每个链表的记录长度,也可以可以只用一个变量来记录两个链表的长度差值。
- 判断一下两个链表的尾节点是否相同(如果有相交节点的话,尾节点是一定相同的,因为一个节点只有一个 next ),如果不相同直接返回 null ,即两链表不相交。
- 反之,通过差值(条件运算符)将p指向长链表的头节点,q 指向短链表的头节点。让长链表先走差值步,然后两个链表一起走,如果相遇,该节点即为第一个相交节点。(如果两链表相交的话,从第一个相交结点开始到尾节点,长度一定是一样的)。
话不多说直接上代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
ListNode p = headA, q = headB;
int len = 0; //用len来记录两个链表长度的差值
while (p.next != null) {
p = p.next;
len++;
}
while (q.next != null) {
q = q.next;
len--;
}
if (p != q) {
return null;
}
p = len > 0 ? headA : headB; //始终让p指向更长的链表
q = p == headA ? headB : headA; //让q指向短的链表
len = Math.abs(len);
while (len != 0) {
p = p.next; //让长链表先走差值步
len--;
}
while (p != q) { //然后两个链表一起走
p = p.next; //如果p=q,即该节点为第一个相交节点
q = q.next;
}
return p;
}
}
又一题又一题!!!
加油!!
小彩蛋
去对方的轨迹里寻找对方的身影,最终相遇在公共节点。是很浪漫的算法。