剑指offer.36.两个链表的第一个公共结点
题目描述
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
代码实现
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode nHead1 = pHead1, nHead2 = pHead2;
while (nHead1 != nHead2) {
nHead1 = nHead1 == null ? pHead2 : nHead1.next;
nHead2 = nHead2 == null ? pHead1 : nHead2.next;
}
return nHead1;
}
}
分析
最直接的思路是遍历一条链表,并将每个结点存在一个集合中,然后遍历另一条链表,判断是否有结点在集合中。
技巧性的方法就是将链表拼接。
对于两个链表,若长度相同,很显然都从头开始遍历,判断是否发现相同结点;若长度不同,则不可以用这样的方法。那么如何构造两个长度相同的链表呢?答案就是a+b = b+a。例如,a=1->2->3->4->5,b=0->4->5,此时直接遍历显然不行,拼接后得到两个链表
1->2->3->4->5->0->4->5
0->4->5->1->2->3->4->5
可以发现相同结点为4号结点
而长度相同的链表拼接后也不会增加遍历的时间,因为最极端的情况是没有找到相同结点,此时二者均为null,循环直接退出。
因此拼接法才是此题的正解,时间复杂度O(m+n),空间复杂度O(1)