image.png

    思路: 方法一: 判断两个链表是否相交,可以使用哈希集合存储链表节点。首先遍历链表 headA,并将链表 headA 中的每个节点加入哈希集合中。然后遍历链表 headB,对于遍历到的每个节点,判断该节点是否在哈希集合中。 方法二: 使用双指针去遍历A链表和B链表。 当链表headA 和headB 都不为空时,创建两个指针pA 和 pB,初始时分别指向两个链表的头节点 headA 和 headB,然后将两个指针依次遍历两个链表的每个节点。具体做法如下: 每步操作需要同时更新指针 pA 和 pB。 如果指针 pA 不为空,则将指针pA 移到下一个节点;如果指针 pB 不为空,则将指针 pB 移到下一个节点。 如果指针pA 为空,则将指针pA 移到链表 headB 的头节点;如果指针pB 为空,则将指针 pB 移到链表 headA 的头节点。 当指针pA 和pB 指向同一个节点或者都为空时,返回它们指向的节点或者null。 原理: 假设A未相交部分为a,B未相交部分为b,相交部分未c 。 在指针 pA 移动了 a+c+b次、指针 pB 移动了b+c+a 次之后,两个指针会同时到达两个链表相交的节点。

    1. public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    2. if (headA == null || headB == null) {
    3. return null;
    4. }
    5. ListNode pointA = headA;
    6. ListNode pointB = headB;
    7. while (pointA != pointB) {
    8. pointA = pointA == null ? headB : pointA.next;
    9. pointB = pointB == null ? headA : pointB.next;
    10. }
    11. return pointA;
    12. }

    image.png

    思路: image.png 假设一个快指针 fast (每次移动2格)和慢指针 slow (每次移动1格) fast = 2slow 假设b点时第一次相遇 这时 2(a+b) = a+n(b+c)+b ==》 a = c +(n-1 )(b+c) 此时当发现 slowfast 相遇时,我们再额外使用一个指针ptr,ptr 速度和 slow 相同。 这时,当ptr 走到入环点的时候,slow 走了 c +(n-1 )(b+c)的距离,正好在入环点相遇。

    1. public ListNode detectCycle(ListNode head) {
    2. ListNode fast = head;
    3. ListNode slow = head;
    4. ListNode p = head;
    5. boolean hasCycle = false;
    6. while (fast.next != null && fast.next.next != null) {
    7. fast = fast.next.next;
    8. slow = slow.next;
    9. if (fast == slow) {
    10. hasCycle = true;
    11. break;
    12. }
    13. }
    14. if (hasCycle) {
    15. while (p != slow) {
    16. p = p.next;
    17. slow = slow.next;
    18. }
    19. }
    20. return slow;
    21. }