输入两个链表,找出它们的第一个公共结点。
难点:公共节点如何理解?
公共节点 指的是 公共节后的内容是一样的,
https://www.nowcoder.com/questionTerminal/6ab1d9a29e88450685099d45c9e31e46
先统计两个链表的长度,如果两个链表的长度不一样,就让链表长的先走,直到两个链表长度一样,这个时候两个链表再同时每次往后移一步,看节点是否一样,如果有相等的,说明这个相等的节点就是两链表的交点,否则如果走完了还没有找到相等的节点,说明他们没有交点,直接返回null即可,来画个图看一下。
public ListNode FindFirstCommonNodeII(ListNode pHead1, ListNode pHead2) {
ListNode current1 = pHead1;// 链表1
ListNode current2 = pHead2;// 链表2
if (pHead1 == null || pHead2 == null)
return null;
int length1 = getLength(current1);
int length2 = getLength(current2);
// 两连表的长度差
// 如果链表1的长度大于链表2的长度
if (length1 >= length2) {
int len = length1 - length2;
// 先遍历链表1,遍历的长度就是两链表的长度差
while (len > 0) {
current1 = current1.next;
len--;
}
}
// 如果链表2的长度大于链表1的长度
else if (length1 < length2) {
int len = length2 - length1;
// 先遍历链表1,遍历的长度就是两链表的长度差
while (len > 0) {
current2 = current2.next;
len--;
}
}
//开始齐头并进,直到找到第一个公共结点
while(current1!=current2){
current1=current1.next;
current2=current2.next;
}
return current1;
}
// 求指定链表的长度
public static int getLength(ListNode pHead) {
int length = 0;
ListNode current = pHead;
while (current != null) {
length++;
current = current.next;
}
return length;
}
https://blog.nowcoder.net/n/8cbed9b696b4457a85c186d209a683c6?f=comment
看下面的链表例子:
0-1-2-3-4-5-null
a-b-4-5-null
代码的ifelse语句,对于某个指针p1来说,其实就是让它跑了连接好的的链表,长度就变成一样了。
如果有公共结点,那么指针一起走到末尾的部分,也就一定会重叠。看看下面指针的路径吧。
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就是该结点,如果不存在那么p1将会是null。
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if(pHead2 == null || pHead1 == null) return null;
ListNode a1 = pHead1, a2 = pHead2;
// 重点是构造2个长度一样的链表,分别将彼此的链表接到自身的尾节点上
while(a1 != a2) {
a1 = a1.next;
a2 = a2.next;
if(a1 != a2){
if(a1 == null) a1=pHead2;
if(a2 == null) a2=pHead1;
}
}
return a1;
}
}
简化后的代码: