题目描述
题目链接:https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/
输入两个链表,找出它们的第一个公共节点。
如下面的两个链表:
在节点 c1 开始相交。
- 如果两个链表没有交点,返回 null.
- 在返回结果后,两个链表仍须保持原有的结构。
- 可假定整个链表结构中没有循环。
- 程序尽量满足 O(n)时间复杂度,且仅用 O(1) 内存。
分析解答
我们很自然的想到链表的查找访问必须从头开始进行遍历,而且对于此题而言,想要找到公共节点必须从两个链表的头开始遍历,所以可以自然的想到使用双指针,如图所示:
那么问题来了,可以想到用双指针,但是怎么去查询到公共节点呢,我们可以看到 A 链表的长度为5
,而 B 链表的长度为6
,而公共部分长度为3,那么说明A链表只需要走2
步就可以到达公共节点,而B需要走3
步才可以到达公共节点,我们可以发现一个规律:2 + 6 = 3 + 5
,可以很自然的想到解决方法就是定义两个指针同时从各自的头结点出发,如果为 NULL 的时候就从另一个链表的头节点重新开始,这样两个指针最终一定会相遇到公共节点。
但是如果是这种情况怎么办:
打眼一看觉得没有公共节点,必然会无限循环下去,可是换个思路,比如这样:
我们假设两个不相交的链表最终指向同一个空节点,那么上述方法就适用了,最终会返回 NULL 值。
解题代码
public class JZ52 {
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
if (headA == headB) return headA;
ListNode curNodeA = headA;
ListNode curNodeB = headB;
while (curNodeA != curNodeB) {
curNodeA = curNodeA == null ? headB : curNodeA.next;
curNodeB = curNodeB == null ? headA : curNodeB.next;
}
return curNodeA;
}
}