判斷兩個鏈表是否相交

這是一道比較綜合的題目。將鏈表中關於環和相交的問題聚集在一起了,關鍵是要思路清晰。

思路如下:

/*
     * 判斷鏈表是否有環
     *     1 如果一個有環一個無環,則肯定不相較
     *     2 如果都無環,則遍歷到尾部,看看最後一個節點是否相等即可
     *          如果要找到第一個相交的點,則讓長的鏈表先走len1-len2步,再同時走,找到相等的節點即可
     *     3 如果都有環,則先找到各自的環入口點(快慢指針,第一次相遇後,快指針從頭節點開始,每次走一步,慢指針繼續向前走一步,直至再次相遇)
     *          如果兩個入口點相等,則肯定相交
     *              如果要找到第一個相交的點,則需要讓長的鏈表(從頭節點到相交的節點)先走len1-len2步,然後同時走,找到相等的點即可
     *          如果兩個入口點不相等,則選其中一個相交點,繼續向後走,看看 是否會經歷另外一個相交點,如果經歷了,則相交,否則不相交
     */

具體代碼如下:

public boolean chkInter(ListNode head1, ListNode head2, int adjust0, int adjust1) {
        if(head1==null || head2==null) return false;
        ListNode node1 = chkLoop(head1);
        ListNode node2 = chkLoop(head2);
        //判斷是否有環
        if(node1==null && node2==null) { //兩個都是無環鏈表
            while(head1.next!=null) {
                head1 = head1.next;
            }
            while(head2.next !=null) {
                head2 = head2.next;
            }
            if(head1==head2) {
                return true;
            } else {
                return false;
            }
        } else if(node1!=null && node2!=null) {//兩個都是有環鏈表
            //node1和node2是環的入口點
            if(node1==node2) {
                return true;
            } else {
                ListNode cur = node1.next;
                while(cur!=node1) {
                    if(cur == node2) { //相交
                        return true;
                    }
                    cur = cur.next;
                }
                //不相交
                return false;
            }
        } else { //一個有環一個無環
            return false;
        }
    }

    private ListNode chkLoop(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while(fast!=null && fast.next!=null) {
            slow = slow.next;
            fast = fast.next.next;
            if(slow==fast) {
                break;
            }
        }
        //沒有環則返回null
        if(fast==null || fast.next==null) return null;
        fast = head;
        while(slow!=fast) {
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章