鏈表中環的入口節點

題目描述

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

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead){
        
    }
}

解法一

遍歷鏈表的時候,用一個容器list依次裝入鏈表的節點,若是發現有重複的節點,那麼就是鏈表的環的入口節點oop

import java.util.ArrayList;
public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead){
        ArrayList<ListNode> list = new ArrayList<>();
        while (!list.contains(pHead) && pHead != null){
            list.add(pHead);
            pHead = pHead.next;
        }

        return pHead;
    }
}

時間複雜度:O(n^2)this

解法二

採用雙指針的方法(這個方法還能夠用來判斷鏈表中有沒有環),一個快指針一個慢指針,快指針一次走兩步,慢指針一次走一步,若是鏈表中有環,那麼兩個指針必定就能夠相遇,而且相遇的地方,必定在環的某處spa

設相遇的地方距環的入口點一邊有a個節點,一邊有b個節點,鏈表除環之外有x個節點,環中一共有c個節點(c=a+b).net

那麼能夠獲得以下關係式,用b = c -a表示指針

![圖片描述][1]code

public ListNode EntryNodeOfLoop(ListNode pHead){
        if(pHead == null || pHead.next == null)return  null;
        ListNode slow = pHead.next;
        ListNode fast = pHead.next.next;
        while (slow != fast && pHead != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        slow = pHead;
        while(slow != fast){
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }

該方法的時間複雜度爲O(n)blog

參考

《劍指offer》——鏈表中環的入口結點圖片

相關文章
相關標籤/搜索