【leetcode】55. 鏈表中環的入口結點

問題描述

給一個鏈表,若其中包含環,請找出該鏈表的環的入口結點,否則,輸出null。

思路

單鏈表如果有環,則這個環肯定在尾巴上。 而且,環的開頭和結尾都是一個結點。所以我們可以用Hash表在時空複雜度都是O(n)的情況下解決這個問題。(方法一)
可以再進行優化。用快慢指針。快慢指針判斷有環的情況就是快指針等於慢指針,但是相遇點只能證明在環上,不能證明這就是環的起點。那咋整? 經過分析我們發現,在環上相遇時,快指針一定比慢指針多走了整數個環的長度。而這整數個環的長度,則就是慢指針走過的距離。所以說,只要此時把快指針指向pHead, 速度變慢,則慢指針與快指針相遇之處就是環的起始點。時間複雜度O(n), 空間複雜度O(1)。(方法二)

方法一

class Solution {
    Set<ListNode> set = new HashSet<>();
    public ListNode EntryNodeOfLoop(ListNode pHead) {
        if(pHead == null) return null;
        while(pHead != null){
            if(set.contains(pHead)){
                return pHead;
            }
            set.add(pHead);
            pHead = pHead.next;
        }
        return null;
    }
}

方法二

class Solution {
    public ListNode EntryNodeOfLoop(ListNode pHead) {
        if(pHead == null || pHead.next == null) return null;
        ListNode low,fast;
        low = fast = pHead; // 站在同一起跑線
        while(low != null && fast != null){
            low = low.next;
            if(fast.next != null) fast = fast.next.next;
            else return null;
            if(low == fast){
                // 肯定有環
                fast = pHead;
                while(fast != low){
                    low = low.next;
                    fast = fast.next;
                }
                return fast;
            }
        }
        return null;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章