1. 程式人生 > >【劍指Offer學習】【面試題56:連結串列中環的入口結點】

【劍指Offer學習】【面試題56:連結串列中環的入口結點】

題目:一個連結串列中包含環,如何找出環的入口結點?

解題思路

  可以用兩個指標來解決這個問題。先定義兩個指標P1和P2指向連結串列的頭結點。如果連結串列中環有n個結點,指標P1在連結串列上向前移動n步,然後兩個指標以相同的速度向前移動。當第二個指標指向環的入口結點時,第一個指標已經圍繞著環走了一圈又回到了入口結點。
  剩下的問題就是如何得到環中結點的數目。我們在面試題15的第二個相關題目時用到了一快一慢的兩個指標。如果兩個指標相遇,表明連結串列中存在環。兩個指標相遇的結點一定是在環中。可以從這個結點出發,一邊繼續向前移動一邊計數,當再次回到這個結點時就可以得到環中結點數了。

結點定義

    private static class ListNode {
        private int val;
        private ListNode next;

        public ListNode() {
        }

        public ListNode(int val) {
            this.val = val;
        }

        @Override
        public String toString() {
            return val +"";
        }
    }

程式碼實現

public class Test56 {
    private static class ListNode {
        private int val;
        private ListNode next;

        public ListNode() {
        }

        public ListNode(int val) {
            this.val = val;
        }

        @Override
        public String toString() {
            return
val +""; } } public static ListNode meetingNode(ListNode head) { ListNode fast = head; ListNode slow = head; while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; if (fast == slow) { break; } } // 連結串列中沒有環 if (fast == null || fast.next == null) { return null; } // fast重新指向第一個結點 fast = head; while (fast != slow) { fast = fast.next; slow = slow.next; } return fast; } public static void main(String[] args) { test01(); test02(); test03(); } // 1->2->3->4->5->6 private static void test01() { ListNode n1 = new ListNode(1); ListNode n2 = new ListNode(2); ListNode n3 = new ListNode(3); ListNode n4 = new ListNode(4); ListNode n5 = new ListNode(5); ListNode n6 = new ListNode(6); n1.next = n2; n2.next = n3; n3.next = n4; n4.next = n5; n5.next = n6; System.out.println(meetingNode(n1)); } // 1->2->3->4->5->6 // ^ | // | | // +--------+ private static void test02() { ListNode n1 = new ListNode(1); ListNode n2 = new ListNode(2); ListNode n3 = new ListNode(3); ListNode n4 = new ListNode(4); ListNode n5 = new ListNode(5); ListNode n6 = new ListNode(6); n1.next = n2; n2.next = n3; n3.next = n4; n4.next = n5; n5.next = n6; n6.next = n3; System.out.println(meetingNode(n1)); } // 1->2->3->4->5->6 <-+ // | | // +---+ private static void test03() { ListNode n1 = new ListNode(1); ListNode n2 = new ListNode(2); ListNode n3 = new ListNode(3); ListNode n4 = new ListNode(4); ListNode n5 = new ListNode(5); ListNode n6 = new ListNode(6); n1.next = n2; n2.next = n3; n3.next = n4; n4.next = n5; n5.next = n6; n6.next = n6; System.out.println(meetingNode(n1)); } }

執行結果

這裡寫圖片描述