思路:採用「快慢指標」查檢查鍊錶是否含有環。讓乙個指標一次走一步,另乙個一次走兩步,如果鍊錶中含有環,快的指標會再次和慢的指標相遇。
這裡需要注意的一點是演算法中迴圈的條件,這是乙個很容易被忽略的細節。
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...