若是有一個單向鏈表,鏈表當中有可能出現"環",就像下圖這樣,如何判斷這個鏈表是有環鏈表?後端
方案一:暴力法緩存
從頭節點,依次遍歷單鏈表的每個節點,每到一個新的節點就頭節點從新遍歷以前的全部的節點,對比此時的節點,若是相同,證實該節點遍歷過兩次,以此說明鏈表是有環的spa
Node p = head.next
while(p.next!==null){
Node c = head
while(c!==p){
c=c.next
}
if(c.next!==p.next){
return true
}
p = p.next
}
return false;
複製代碼
此方案時間複雜度爲O(n^2),空間複雜度爲O(1)指針
第二種方案:用hashMap緩存遍歷的過的節點code
仍是頭節點進行遍歷,每一次遍歷新的節點時,對比存儲到hashMap集合是否有相同的節點,有,證實有環,無,存儲到集合中cdn
僞代碼:blog
Node p = head
HashMap hm = new HashMap()<Node,Node>
while(p!=null){
if(hm.get(p)){
return true
}
hm.put(p,p)
p =p.next
}
複製代碼
第三種方案:雙指針遍歷後端開發
首先建立兩個指針1和2,同時指向這個鏈表的頭節點。而後開始一個大循環,在循環體中,讓指針1每次向下移動一個節點,讓指針2每次向下移動兩個節點,而後比較兩個指針指向的節點是否相同。若是相同,則判斷出鏈表有環,若是不一樣,則繼續下一次循環開發
僞代碼:get
Node p = head
Node q = head.next
while(p!==q){
if(p.next==null) return false
p =p.next
if(q.next==null) return false
if(q.next.next==null) return false
q = q.next.next
}
return true
複製代碼
此方案的時間複雜度爲O(n),空間複雜度爲O(1)
考拉後端開發小哥Rowland,熱愛運動還有點萌!