160. Intersection of Two Linked Lists
一、题目
1、审题
2、分析
给出两个单向链表,如果两个链表用重叠部分,输出重叠节点的第一个节点,否则输出 null;
二、解答
1、思路:
方法一、
将两个链表按照尾部进行对齐,在开始遍历链表,查找是否存在重叠节点。
①、计算两个链表长度;
②、将长的链表向后移动,使得两链表尾部对齐;
③、开始查找节点。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) { int lenA = 0, lenB = 0; ListNode node = headA; // step1: 计算 A、B 节点长度 while(node != null) { node = node.next; lenA++; } node = headB; while(node != null) { node = node.next; lenB++; } // step2: 使 A、B按照尾部对齐,开始同时向后遍历 if(lenA > lenB) { node = headA; int gap = lenA - lenB; while(gap-- > 0) headA = headA.next; } else if(lenA < lenB) { node = headB; int gap = lenB - lenA; while(gap-- > 0) headB = headB.next; } // step3: 查找目标节点 while(headA != null && headB != null) { if(headA == headB) return headA; headA = headA.next; headB = headB.next; } return headA; }
方法二、
无需计算链表长度。
①、采用指针 a 指向 headA, 指针指向 headB;
② 、采用一个 while 循环,当 a != b 时,a、b均向后移动,当 a = null 时, a 指向 headB,当 b = null 时, b 指向 headA。
最终,a 会分别遍历了 headA + headB,b会遍历了 headB + headA,最终 a、b 相遇,相遇点为 null(无重叠节点)或 node(重叠的第一个节点).
public ListNode getIntersectionNode2(ListNode headA, ListNode headB) { if(headA == null || headB == null) return null; ListNode a = headA, b = headB; while(a != b) { a = (a == null ? headB : a.next); b = (b == null ? headA : b.next); } return a; }