牛客: 两个链表的第一个公共节点
1. 常规方法(求链表长度差,长的先走长度差,再同时走)
- 分别求两个单链表的长度,len1 和 len2,计算长度差 len
- 然后让长的链表先走 len 步,此时
p1 和 p2 链表剩余长度相同
- p1 和 p2 同时走,直到 p1 == p2 ,若有共同节点,p1 != null,否则 p1 为 null
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
int len1 = getLen(pHead1), len2 = getLen(pHead2);
int len = len1 >= len2 ? len1 - len2 : len2 - len1;
if (len1 >= len2) {
pHead1 = go(pHead1, len);
}else {
pHead2 = go(pHead2, len);
}
// 同时走
while (pHead1 != pHead2) {
pHead1 = pHead1.next;
pHead2 = pHead2.next;
}
// 有共同节点,pHead1 != null, 否则 pHead1 == null
return pHead1;
}
// 计算链表长度
public int getLen(ListNode p) {
int len = 0;
while (p != null) {
len++;
p = p.next;
}
return len;
}
// 长的链表先走 len 步
public ListNode go(ListNode p, int len) {
while (len != 0) {
p = p.next;
len--;
}
return p;
}
}
2. 收尾相接法(两个指针走完自己的接着走对方的, 最终走相同长度)
- p1 和 p2 同时走
- p1 走完接着 p2 头部走,同理 p2 走完接着 p1 头部走
- 直到 p1 == p2,若有共同点,p1 != null(中间停止),否则 p1 为 null (走到尾部)
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode p1 = pHead1, p2 = pHead2;
while (p1 != p2) {
p1 = (p1 == null ? pHead2 : p1.next);
p2 = (p2 == null ? pHead1 : p2.next);
}
return p1;
}