【整理】160 相交链表

232 阅读1分钟

题目

leetcode-cn.com/problems/in… 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

思路1

两个指针A、B,让这俩指针都走一遍headA+headB,如果有交点,肯定会相遇(因为如果有交点,交点之后的路程肯定是一样的,然后俩指针又走一样的总路程headA+headB,所以如果相遇,一定在交点。)

代码1

这一题可以不用写边界,但是最好每题一开始都写一下边界。

    public ListNode getIntersectionNode(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;
    }
        
}

上面的代码是看了评论改进的,真的是优雅。一开始根据思路写的代码是这样的:

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode A = headA,B = headB;
        while (A != B){
             while(A != null && B != null){            
                  A = A.next;
                  B = B.next;
             }
             if (A == null){
                  A = headB;
             }
             if (B == null){
                 B = headA;
             }        
        }
        return A;
    }
}

多个循环嵌套,超出了时间限制,(按理说应该是O(n^2),怎么会超限制呢?)

思路2

一个很巧的思路,就是先让一个链表成环,然后在快慢指针判断环,相遇返回交点。最后记得复原链表。环找环起点刚好有一题,放下一题再将吧。

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null){
            return null;
        }
        ListNode A = headA ;
        while(A.next != null){
            A = A.next;
        }
        A.next = headA;

        ListNode fast = headB;
        ListNode slow = headB;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(slow == fast){
                slow = headB;
                while(slow != fast){
                    slow =slow.next;
                    fast = fast.next;
                }
                A.next = null;
                return slow;
            }
        }
        A.next = null;
        return null;
        

        
    }
}