判斷鍊錶是否有環以及尋找環入口

2021-06-20 04:03:19 字數 1316 閱讀 5330

思路:採用「快慢指標」查檢查鍊錶是否含有環。讓乙個指標一次走一步,另乙個一次走兩步,如果鍊錶中含有環,快的指標會再次和慢的指標相遇。

這裡需要注意的一點是演算法中迴圈的條件,這是乙個很容易被忽略的細節。

1)因為fast指標比slow指標走得快,所以只要判斷fast指標是否為空就好。由於fast指標一次走兩步,fast.next可能已經為空(當fast為尾結點時),fast.next.next將會導致nullpointerexception異常,所以在while迴圈中我們要判斷fast.next是否為空;

2)考慮乙個特殊情況,當輸入的鍊錶為空時,演算法應該返回false,空鍊錶肯定是不含有環的。如果沒有fast != null,也會導致fast.next丟擲nullpointerexception異常。

**:

public boolean hascycle(listnode head) 

listnode slow = head;

listnode fast = head;

while(fast != null && fast.next != null)

}return false;

}

第1題中判斷出了鍊錶是否有環,那麼如果要尋找環的入口呢?

如下圖所示:

x表示頭指標(a)到環的入口點(b)的距離

y表示環的入口點(b)到第一次相遇點(c)的距離

z表示第一次相遇點(c)到環的入口點(b)的距離。

假設慢指標走了s,那麼快指標的速度是它的兩倍,那麼快指標走的路程為2s,所以有以下等式:

x+y=s

x+y+z+y=x+2y+z=2s

那麼2(x+y)=x+2y+z,最終得出x=z。

也就是說,慢指標從頭開始走,快指標繼續往前走,它們的相遇點就是環的入口b。

如果沒有環,返回空指標。

**如下:

listnode* entrynodeofloop(listnode* phead)

listnode* slow = phead;

listnode* fast = phead;

bool has_cycle = false;

while (slow && fast && fast->next)

}if (!has_cycle)

slow = phead;

while (slow != fast)

return slow;

}

判斷鍊錶是否有環及環的入口

1.如何判斷是否有環?如果有兩個頭結點指標,乙個走的快,乙個走的慢,那麼若干步以後,快的指標總會超過慢的指標一圈。2.如何計算環的長度?第一次相遇 超一圈 時開始計數,第二次相遇時停止計數。3.如何判斷環的入口點 碰撞點p到連線點的距離 頭指標到連線點的距離,因此,分別從碰撞點 頭指標開始走,相遇的...

鍊錶判斷是否存在環以及環的入口

快慢指標的方法 class solution else return false if pfast plow return true return false 快慢指標的方法 分為兩個階段,第一階段先尋找是否有環,第二階段通過快慢指標的回合點找到環的入口。借用leetcode上的圖來說明 首先環的長...

判斷鍊錶是否有環,入口節點以及環的大小(C )

這篇部落格對上述問題有詳細的解釋 判斷鍊錶中是否有環 有關單鏈表中環的問題 這裡只做c 的乙個 實現,主要包含構建環形鍊錶,判斷是否有環以及環的大小。include include using namespace std struct node node creatcircularlist newn...