面試官:你來說說怎麼判斷鏈表有環?
AXin:什…什麼是鏈表有環?
面試官:環都不知奧?喝烏俺~huan,環,就是下面這個樣子,只會出現情況1和情況2,不會出現情況3這種。而且環有且只有一個,一定包含最後一個節點。(PS:情況3已經是有向圖了,不是鏈表)
AXin:我…我想一想。
面試官:別墨跡了,你就說你會不會吧?
【30分鐘後…】
AXin:我想到了!
面試官:快說!我兩把王者都打完了!
AXin:好嘞!用兩個指針,指針A一次向前走一步,指針B一次向前走兩步,如果指針A和指針B能夠相遇,說明鏈表中有環。
面試官:算你聰明,解釋解釋怎麼個走法。
AXin:我拿張紙劃給你看,你就知道了。
【片刻之後…】
AXin:噹噹噹當!看圖!
面試官:不錯!有那味兒了。圖畫得挺好!你懂美術?
AXin:略懂~ 略懂~
面試官:光畫圖沒用,你給我把代碼寫出來!
AXin:好!
【片刻之後】
AXin:請您過目!
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struct ListNode *head) {
if(NULL == head)
return false;
struct ListNode *fast = head;
struct ListNode *slow = head;
// 注意fast->next可能爲空指針
while(slow && fast && fast->next){
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
return true;
}
return false;
}
面試官:好!明天來上班!
此種方法使用了兩個指針,一個走得快,一個走得慢,稱爲“快慢指針”法。除了判斷鏈表中是否有環,還可以解決其他類似的問題,例如:找出單鏈表中倒數第K個元素。可以思考一下怎麼解決。