1.如何判斷單鏈表是否有環?
image.png
image.png
第一種是尾節點指向頭節點;第二種是尾節點指向鏈表中的某一個節點
解法一:追及法,設置兩個指針一個是slow另一個是fast。slow一次走一個節點,fast一次走兩個節點,這樣一來當fast追上slow時也就是fast和slow重合時就說明鏈表中有環。
解法二:哈希法,維護一個哈希表,接著遍歷鏈表將元素或每個節點的地址存入哈希表中,如果出現重復就代表鏈表有環。
第一種解法時間復雜度高但是不需要額外的內存空間,第二種方法時間復雜度低但是需要額外空間來儲存哈希表。
2.計算環的長度:
解法一之后,slow和fast的碰撞點開始,繼續走,slow一次走一步,fast一次走兩步,第二次碰撞時所經過的操作數就是環的長度。
3.計算環的入口點:
解法一之后,當fast若與slow相遇時,slow肯定沒有走遍歷完鏈表,而fast已經在環內循環了n圈(1<=n)。假設slow走了s步,則fast走了2s步(fast步數還等于s 加上在環上多轉的n圈),設環長為r,則:
2s = s + nr
s= nr
設整個鏈表長L,入口環與相遇點距離為x,起點到環入口點的距離為a。
a + x = nr
a + x = (n – 1)r +r = (n-1)r + L - a
a = (n-1)r + (L – a – x)
(L – a – x)為相遇點到環入口點的距離,由此可知,從鏈表頭到環入口點等于(n-1)循環內環+相遇點到環入口點,于是我們從鏈表頭、與相遇點分別設一個指針,每次各走一步,兩個指針必定相遇,且相遇第一點為環入口點。