题目
输入两个链表,找出它们的第一个公共结点。
思路分析
- 否定第一反应:第一眼看到题目,觉得是给两个数表,然后找重复元素中的第一个。但是仔细思考一下,对“第一”的判定实在是不准确(最先出现?)
书中关键点:若两个单链表有公共节点,则公共节点之后的链表必定是相同的——“合流”
公共点的性质:来自不同链表的指针重合(pHead1 == pHead2;)
- 遍历指针对齐:计算链表长度,较长的指针进行对齐
- 时空复杂度较好,O(n),O(1)
代码如下:
public class FindFirstCommonNode {
public int length(ListNode head) {
int count = 0;
if (head == null) return count;
ListNode ln = head;
while (ln != null) {
++count;
ln = ln.next;
}
return count;
}
public ListNode findFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null)
return null;
int length1 = length(pHead1);
int length2 = length(pHead2);
int dist = length1 - length2;
//pHead1 is longer than pHead2
if (dist > 0) {
for (int i = 1; i <= dist; i++) {
pHead1 = pHead1.next;
}
}
//pHead2 is longer than pHead1
if (dist < 0) {
for (int i = dist; i < 0; i++) {
pHead2 = pHead2.next;
}
}
while (pHead1 != null && pHead2 != null) {
if (pHead1 != pHead2) {
pHead1 = pHead1.next;
pHead2 = pHead2.next;
} else
return pHead1;
}
return null;
}
}