問題描述
給一個鏈表,若其中包含環,請找出該鏈表的環的入口結點,否則,輸出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;
}
}