一、题目
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:

题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
二、思路
1)获取长度+双指针
观察题目给出的链表,如果进行两个指针移动,怎么知道另一个指针访问过?
由于相交链表的最后一段是共同拥有的,所以从相交节点开始到最末端的长度相等(也就是图中c1、c2、c3),可以采用以下思路:
1、获取A链表长度和B链表长度 2、将A和B的遍历指针对齐(比如B链表需要移动到b2位置),确保到相交节点的位置距离相等 3、同时移动两个遍历指针,判断两个指针指向对象是否是同一个
还有不相交的情况需要考虑,如果两个指针指向了末尾节点都不相等,它们会继续向下指向null,这个判断是相等的,满足题目要求的返回值。
2)哈希表
如果需要快速解题,最简单的思路就是使用哈希表记录A链表的所有节点,然后遍历B链表查询是否存在该节点。
逻辑清晰,代码量少,适合先验证逻辑。但耗时较多。
三、代码
1)获取长度+双指针
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {int lenA = getLength(headA);int lenB = getLength(headB);int diff = lenA - lenB;if (diff > 0) {while (diff-- > 0) {headA = headA.next;}} else {while (diff++ < 0) {headB = headB.next;}}while (headA != headB) {headA = headA.next;headB = headB.next;}return headA;}private int getLength(ListNode head) {int len = 0;while (head != null) {len++;head = head.next;}return len;}}
时间复杂度为O(max(lenA, lenB)),空间复杂度为O(1)。
2)哈希表
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {Set<ListNode> set = new HashSet();while (headA != null) {set.add(headA);headA = headA.next;}while (headB != null) {if (set.contains(headB)) {return headB;}headB = headB.next;}return headB;}}
时间复杂度为O(lenB*log(lenA)),空间复杂度为O(lenA)。
