尋找單向鍊錶中含有環的入口節點

2021-08-01 02:38:13 字數 1972 閱讀 8108

這是乙個比較基本的鍊錶問題。總結一下,可以擴充套件為以下幾類問題:

解法:具體**如下:

定義listnode資料結構

public

class listnode

/**

* 判斷單向鍊錶是否有環

*@param phead

*@return

*/public

boolean

hasloopinlistnode(listnode phead)

listnode slow = phead;

listnode fast = phead;

while(slow !=null&&fast.next !=null)

return

false;

}

/**

* 求環的長度

*@param phead

*@return

*/public

intlengthoflooplistnode(listnode phead)

listnode slow = phead;

listnode fast = phead;

//記錄快慢指標第一次相遇之後為起點,直至第二次相遇所走過的步長

int step = 0;

while(slow !=null&&fast.next !=null)

}if(fast==null||fast.next == null)

//此時,fast停留在首次碰撞的節點

while(fast.val != slow.next.val)

return step;

}

又因為fast的速度是slow的兩倍,所以fast走過的距離是slow走過的兩倍,所以,l2 = 2*l1。即有2(a+b) = a+b+c+b。很容易得出,a = c,也就是說,頭指標到連線點的距離,就是快慢指標首次相遇的碰撞點到連線點的距離。

所以在求連線點位置這個問題時,已經在第二問中求出了碰撞點p的位置(圖中為z),則可以讓slow從頭結點開始,fast從碰撞點z開始,每次分別走一步,直至相遇,因為a=c,所以相遇時,一定在連線點y處

/**

* 找出連線點

* @param phead

* @return

*/public listnode getfirstjoin(listnode phead)

listnode slow = phead;

listnode fast = phead;

//找出第一次碰撞的點

while(slow !=null&&fast.next !=null)

}slow = phead;

while(slow.val != fast.val)

return slow;

}

/**

* 求帶環鍊錶長度

*@param phead

*@return

*/public

intgetlooplength(listnode phead)

listnode slow = phead;

listnode fast = phead;

//頭結點到連線點的距離

int lengthtojoin = 0;

//環長度

int lengthofloop = lengthoflooplistnode(phead);

//找出第一次碰撞的點

while(slow !=null&&fast.next !=null)

}slow = phead;

while(slow.val != fast.val)

return lengthofloop+lengthtojoin;

}

鍊錶中的環入口節點

public class 鍊錶中的環入口節點 計算環的長度 int lengthofcycle 1 listnode curnode meetnode while curnode.next meetnode 找出入口節點 利用快慢指標,前者先行lengthofcycle個節點,然後兩者同時前進當fa...

判斷鍊錶是否有環以及尋找環入口

思路 採用 快慢指標 查檢查鍊錶是否含有環。讓乙個指標一次走一步,另乙個一次走兩步,如果鍊錶中含有環,快的指標會再次和慢的指標相遇。這裡需要注意的一點是演算法中迴圈的條件,這是乙個很容易被忽略的細節。1 因為fast指標比slow指標走得快,所以只要判斷fast指標是否為空就好。由於fast指標一次...

判斷鍊錶中的環的入口節點

有乙個單向鍊錶,判斷鍊錶中是否有環,如果有,返回環的入口節點。功能測試 鍊錶中包含或者不包含環,鍊錶有多個或者乙個節點 特殊值測試 頭指標為空 include includeusing namespace std struct listnode listnode hasring listnode h...