判斷鍊錶是否有環的三種方法
1. 在節點listnode中增加乙個域,用於記錄此節點是否已經被訪問,如下listnode中被注釋掉**。此方法簡單,能找出環開始的節點,但是增加了鍊錶的開銷。如果鍊錶非常大 則需要十分大的記憶體來儲存此域。
2. 使用鍊錶逆序的方法。從頭結點開始一直將鍊錶逆序,頭結點的next域為空。如果有環的話鍊錶逆序必定會回到頭節點而終止。這種做法同樣簡單,確保o(n)時間終止演算法。但是修改了鍊錶結構。原鍊錶已經被改變。但是不能找出環開始的節點
3. 使用兩個變數賽跑,乙個變數走兩步/次,乙個變數走一步/次。 如果有環則兩個變數必定會相逢,其中快的變數比慢的變數多走一圈。此演算法 如果鍊錶的環非常大 則需要較大的遍歷時間。此演算法同時也能找出環開始的地方
class listnode
}
方法一、
public class solution
return false;
}}
方法二、
public class solution
return false;
}} return false;
listnode p = head;
listnode q = head.next;
listnode k = head.next.next;
while (k != null)
return false;
}}
方法三、
/*找出環開始的節點證明:設煉表長度為n(每個節點訪問一次) 煉表頭到達環開始節點長度為 s ,環的大小為s因為 快節點比慢節點多跑一圈 到達相遇節點, 設n為迴圈的次數。 所以有 2*n-n=s =》 n=s,即到達相遇節點的時候慢節點相當於剛好走了乙個環的大小。所以慢節點走完鍊錶n剩下的節點為n-s。而從頭節點到環開始的距離s =n-s。所以從頭結點開始和慢節點同時再走n-s步即能在環開始的地方相遇。*/
public class solution
return meetnode;
}public static listnode finenode(listnode head)
} return null;
}}
單鏈表逆序三種方法
需要三個指標,前驅p1,當前p2,後繼p3 結束的條件是p2 null void reverse1 pnode head p1 p2 p2 p3 head next p1 head變成新頭節點返回 else return pnode reverse1 pnode head p1 p2 p2 p3 r...
單鏈表實現反轉的三種方法
單鏈表的操作是面試中經常會遇到的問題,今天總結一下反轉的幾種方案 1 兩兩對換 2,放入陣列,倒置陣列 3,遞迴實現 如下 include include typedef struct node node,pnode pnode createnode phead pnext null int n p...
判斷單鏈表是否有環
1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進一步,fast每次前進二步,如果鍊錶存在環,則fast必定先進入環,而slow後進入環,兩個指標必定相遇。當然,fas...