首先如何判斷乙個鍊錶是否有環:
設定兩個指標
(fast, slow)
,初始值都指向頭,
slow
每次前進一步,
fast
每次前進二步,如果鍊錶存在環,則
fast
必定先進入環,而
slow
後進入環,兩個指標必定相遇。
(當然,
fast
先行頭到尾部為
null
,則為無環鏈表
)程式如下:
bool i***itsloop(slist *head)
return !(fast == null || fast->next == null);
}
下面看如何找這個環的入口:
第一種方法:
當fast
若與slow相遇時,
slow
肯定沒有走遍歷完鍊錶
(這是因為如果這個鍊錶整個是個環的話,當
slow
恰好到達鍊錶終點的時候
fast
正好追上
slow
,當這個環不是整個鍊錶的時候,則肯定在
slow
到達終點的時候就被
fast
追上了)
,而fast
已經在環內迴圈了n圈
(1<=n)。
假設slow走了s
步,則fast
走了2s
步(fast
步數還等於
s加上在環上多轉的
n圈),
設環長為
r,則:
因為2s = s + nr
所以得出
s= nr
設整個鍊錶長
l,環入口
與相遇點距離為
x,起點到環入口點的距離為a。
則有a + x =
s 推出
a = nr-x
分解有a + x = (n – 1)r +r = (n-1)r + l - aa = (n-1)r + (l – a – x)(l – a – x)
為相遇點到環入口點的距離,
由此可知,從煉表頭到環入口點等於(n-1)
迴圈內環
+相遇點到環入口點,
於是我們從煉表頭、與相遇點分別設乙個指標,每次各走一步,兩個指標必定相遇,且相遇第一點為環入口點。程式描述如下:
slist* findloopport(slist *head)
if (fast == null || fast->next == null)
return null;
slow = head;
while (slow != fast)
return slow;
}
兩個**合二為一為
lnode* getloopnode(lnode* head)
//定義乙個快指標和乙個慢指標
lnode* fast = head;
lnode* slow = head;
while (fast && (fast->next))
}return slow;}}
return null;
}
判斷鍊錶是否有環,如果有,找到環的入口位置
判斷乙個鍊錶是否有環,空間複雜度是o 1 如果不考慮空間複雜度,可以使用乙個map記錄走過的節點,當遇到第乙個在map中存在的節點時,就說明回到了出發點,即鍊錶有環,同時也找到了環的入口。不適用額外記憶體空間的技巧是使用快慢指標,即採用兩個指標walker和runner,walker每次移動一步而r...
判斷乙個單鏈表是否有環,如果有,找出環的起始位置
第一種方法是從單鏈表head開始,每遍歷乙個,就把那個node放在hashset裡,走到下乙個的時候,把該node放在hashset裡查詢,如果有相同的,就表示有環,如果走到單鏈表最後乙個node,在hashset裡都沒有重複的node,就表示沒有環。這種方法需要o n 的空間和時間。第二種方法是設...
判斷乙個鍊錶是否有環
1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進一步,fast每次前進二步,如果鍊錶存在環,則fast必定先進入環,而slow後進入環,兩個指標必定相遇。當然,fas...