剑指 Offer 52. 两个链表的第一个公共节点


题目链接

题目描述:


我的题解:

方法一:双指针法

思路分析:

  • 声明两个指针p1,p2 分别指向链表A、链表B。
  • 然后分别同时逐结点遍历
  • 当 p1 到达链表 headA 的末尾时,重新定位到链表 headB 的头结点;当 p2 到达链表 headB 的末尾时,重新定位到链表 headA 的头结点。
  • 如此,当它们相遇时,所指向的结点就是第一个公共结点。
    (p1 p2可以分别遍历完两条链表。同时开始,将可以保证同时遍历结束。又因一旦同时指向第一个相交节点时,剩下的节点数相同;故可以保证p1和p2能同时指向到第一个相交节点(即相遇))

代码如下:

     public ListNode getIntersectionNode(ListNode headA, ListNode headB) {

        if (headA == null || headB == null) return null;

        ListNode p1 = headA;
        ListNode p2 = headB;
        int change =0; // 重定位到链表头的次数和
        while (p1 != p2) {

            if (p1.next == null) {
                p1 = headB; // 重定位到另一链表头
                change++;
            } else p1 = p1.next;

            if (p2.next == null) {
                p2 = headA; // 重定位到另一链表头
                change++;
            } else p2 = p2.next;


            if (change > 2) return null; // 两个指针均已遍历另一条链表了
        }
        return p1;
    }

方法二:也是双指针,但先求链表长度,再同时移动

思路分析:

  • 声明两个指针p1,p2 分别指向链表A、链表B。
  • 稍后做一定的处理后 会同时移动两个指针。
  • 此题中,可以保证两指针最后同时到达链表尾,那么,也就可以保证同时到达相交结点(如果有的话)。
  • 那么,如何保证呢?分别求出两条链表的长度,然后,让长链表对应的指针,先走几步(步数为多出来的节点数)。
  • 做完上一步的处理后,p1和p2再同时移动,便可同时到达链表尾,自然就可以保证同时到达相交节点了(如果有的话)。

代码如下:

     public ListNode getIntersectionNode(ListNode headA, ListNode headB) {

        ListNode p1 = headA;
        ListNode p2 = headB;
        int len1 = getLength(headA);
        int len2 = getLength(headB);

        int different = len1 - len2;
        // 长的指针,先走different步
        if (different > 0) {    // headA 长
            for (int i = different; i > 0; i--) {
                p1 = p1.next;
            }
        } else {    // headB长 或 同样长(different=0,不进for循环了)
            for (int i = -different; i > 0; i--) {
                p2 = p2.next;
            }
        }

        // 接着, p1,p2同时移动。当 p1 p2指向同一节点时,该节点即为题目所求的相交节点
        while (p1!=null && p2!=null && p1 != p2) {
            p1 = p1.next;
            p2 = p2.next;
        }

        return p1;
    }

    private int getLength(ListNode head) {
        int cnt = 0;
        for (ListNode tmp = head; tmp !=null ; tmp = tmp.next) {
            cnt++;
        }
        return cnt;
    }

猜你喜欢

转载自www.cnblogs.com/duduwy/p/13379448.html