题目
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
思路
首先明确什么是公共节点
公共节点指的是两个链表从某一节点开始 next都指向同一节点
比如
0-1-2-3-4-5-null
a-b-4-5-null
4就是他们的第一个公共节点
首先想到的方法是存入map
但有一种更简便的方法
list1 指针p1 list2指针p2
遍历链表 两个指针同时向后移动
如果两个指针不相等时
有一个指针指向空 那就使得这个指针指向后一个链表
即把这两个链表连起来
也就是说上例中我们最后得到的链表是这样的
p1: 0-1-2-3-4-5-null(此时遇到ifelse)-a-b-4-5-null
p2: a-b-4-5-null(此时遇到ifelse)0-1-2-3-4-5-null
还有一点 我们比较的是节点的引用 p1=p2
即不仅值要相等 指向的下一个结点也要相等
如果有公共节点 则输出p1
否则输出 null
因为比较到null时 p1 p2 是相等的
如果两个链表等长 那么只需要一次遍历
如果不等长 就需要连接 相当于每个链表遍历两次
代码
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode p1 = pHead1;
ListNode p2 = pHead2;
if(pHead1 == null || pHead2 == null){
return null;
}
while(p1 != p2){
p1=p1.next;
p2=p2.next;
if(p1 != p2){//这个判断条件是必须的 因为在循环里又重新给p1 p2赋值了
if (p1 == null) p1 = pHead2;
if (p2 == null) p2 = pHead1;
}
}
return p1;
}
}
简易写法 -leetcode
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode p1 = headA;
ListNode p2 = headB;;
if(headA == null || headB == null) return null;
while(p1 != p2){
p1 = p1 != null ? p1.next : headB;
p2 = p2 != null ? p2.next : headA;
}
return p1;
}
}