1. 程式人生 > >LeetCode142之環形連結串列II

LeetCode142之環形連結串列II

一、題目

二、一種解題思路

①方法介紹一:龜兔賽跑法升級版

    方法解析:①使用龜兔賽跑法先判斷當前連結串列是否存在環(快慢指標能夠相遇,則存在環)
                      ②假設連結串列頭部到環起點的距離為x,環的長度為y,快指標每次走兩步,慢指標每次走一步,

                        慢指標走t步後與快指標相遇,相遇的位置是(t - x)%y + x=(2*t - x)%y + x,求得t%y = 0
                        也就是說t是y的整數倍,故從連結串列頭部和相遇的位置一起走x步會重新相遇。

   時間複雜度:O(n)

   空間複雜度:O(n)

②核心程式碼:

/**
     * 查詢環形連結串列的入環節點
     * 方法: ①使用龜兔賽跑法先判斷當前連結串列是否存在環(快慢指標能夠相遇,則存在環)
     * ②假設連結串列頭部到環起點的距離為x,環的長度為y,快指標每次走兩步,慢指標每次走一步,
     * 慢指標走t步後與快指標相遇,
     * 相遇的位置是(t - x)%y + x=(2*t - x)%y + x,求得t%y = 0
     * 也就是t是y的整數倍,故從連結串列頭部和相遇的位置一起走x步會重新相遇。
     *
     * @param head 頭節點
     * @return 環形連結串列的入環節點
     */
    public static ListNode detectCycle1(ListNode head) {
        if (head == null || head.next == null) {
            return null;
        }
        ListNode target1 = head;
        ListNode target2 = head;
        while (target1 != null && target2 != null) {
            target1 = target1.next;
            if (target2.next != null) {
                target2 = target2.next.next;
            } else {
                target2 = target2.next;
            }
            if (target1 == target2) {
                break;
            }
        }
        if (target1 == target2) {
            target1 = head;
            while (target1 != target2) {
                target1 = target1.next;
                target2 = target2.next;
            }
            return target1;
        }
        return null;
    }

③輔助類

public class ListNode {
    public int val;
    public ListNode next;

    public ListNode(int x) {
        val = x;
        next = null;
    }

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

三、LeetCode成功截圖

四、感想

加油,加油,再加油,堅持,堅持,再堅持。