题目
输入两个单向链表,请问如何找出它们的第1个重合节点。例如,图4.5中的两个链表的第1个重合节点的值是4。
分析
首先遍历两个链表得到它们的长度,这样就能知道哪个链表比较长,以及长的链表比短的链表多几个节点。在第2次遍历时,第1个指针P1在较长的链表中先移动若干步,再把第2个指针P2初始化到较短的链表的头节点,然后这两个指针按照相同的速度在链表中移动,直到它们相遇。两个指针相遇的节点就是两个链表的第1个公共节点。
解
java
public class Test {
public static void main(String[] args) {
ListNode listNode1 = new ListNode(1);
ListNode listNode2 = new ListNode(2);
ListNode listNode3 = new ListNode(3);
ListNode listNode4 = new ListNode(4);
ListNode listNode5 = new ListNode(5);
ListNode listNode6 = new ListNode(6);
ListNode listNode7 = new ListNode(7);
ListNode listNode8 = new ListNode(8);
listNode1.next = listNode2;
listNode2.next = listNode3;
listNode3.next = listNode4;
listNode4.next = listNode5;
listNode5.next = listNode6;
listNode7.next = listNode8;
listNode8.next = listNode4;
ListNode result = getIntersectionNode(listNode1, listNode7);
System.out.println(result.val);
}
public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int count1 = countList(headA);
int count2 = countList(headB);
int delta = Math.abs(count1 - count2);
ListNode longer = count1 > count2 ? headA : headB;
ListNode shorter = count1 > count2 ? headB : headA;
ListNode node1 = longer;
for (int i = 0; i < delta; i++) {
node1 = node1.next;
}
ListNode node2 = shorter;
while (node1 != node2) {
node2 = node2.next;
node1 = node1.next;
}
return node1;
}
private static int countList(ListNode head) {
int count = 0;
while (head != null) {
count++;
head = head.next;
}
return count;
}
}