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;
    }

 

posted @ 2018-10-13 17:38  skillking2  阅读(154)  评论(0编辑  收藏  举报