思路一:双指针
如果我们把长的链表多余的头砍去,然后让两个指针分别从双方的头结点出发,那么相遇点就是第一个重合结点
public class Solution {
int getSize(ListNode head) {
int size = 0;
for (; null != head; head = head.next)
size++;
return size;
}
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (null == headA || null == headB)
return null;
int sizeA = getSize(headA), sizeB = getSize(headB);
ListNode longHead = sizeA > sizeB ? headA : headB, shortHead = sizeA <= sizeB ? headA : headB;
for (int i = 0; i < Math.abs(sizeA - sizeB); i++) {
longHead = longHead.next;
}
while (longHead != shortHead) {
longHead = longHead.next;
shortHead = shortHead.next;
}
return longHead;
}
}
思路二:哈希表
先遍历一遍第一个链表,把所有结点放入哈希表中,然后遍历第二个链表,遍历过程中查看哈希表中是否存在当前结点,如果存在,那么当前结点就是第一个重合结点,如果直到最后还未出现,那么就是没有重合结点
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (null == headA || null == headB)
return null;
Set<ListNode> visited = new HashSet<>();
while (null != headA) {
visited.add(headA);
headA = headA.next;
}
while (null != headB) {
if (visited.contains(headB))
break;
headB = headB.next;
}
return headB;
}
}