快慢指针:141. 环形链表(判断是否存在环路)
題目描述
給定一個鏈表,判斷鏈表中是否有環(huán)
題目鏈接
141. 環(huán)形鏈表
解題思路
使用快慢指針(Floyd判圈算法):從鏈表的頭部設(shè)置兩個指針,p1的步長為1, p2的步長為2,同時向前走,如果p1和p2最終能夠相遇,則說明鏈表是有環(huán)的。
檢測環(huán)的基本思想是非常簡單的,可以類比成兩個人在跑道上跑。只要有圈,跑的快的那個人就一定能夠追上跑得慢的那個人。
代碼:
public class Solution {public boolean hasCycle(ListNode head) {if (head == null) {return false;} //設(shè)置快慢指針ListNode slow = head, fast = head.next;while(slow!=null&&fast!=null&&fast.next!=null){if(slow == fast){return true;}slow = slow.next;fast = fast.next.next;}return false;} }擴展
求環(huán)的長度
兩個人相遇的是時候,一定已經(jīng)在環(huán)上了,然后兩個人只要再次在環(huán)上接著跑,再次相遇的時候(也就是所謂的套圈),跑的快的那個人就比跑得慢的人整整多跑了一圈,所以環(huán)的長度也就出來了。
用算法來描述:第一次相遇后,p1和p2按照原來的步長繼續(xù)向前查找,并且記錄下兩個指針遍歷過的節(jié)點個數(shù)。當(dāng)兩個指針再次相遇的時候,遍歷的節(jié)點數(shù)量差就是環(huán)的長度。
求環(huán)的起點
解決方法:
把其中的一個指針重置到鏈表頭部,然后兩個指針步長都為1,繼續(xù)向前移動,相遇的位置即為環(huán)的起點。
解釋:
首先我們設(shè)第一次相遇的時候慢指針走過的節(jié)點個數(shù)為i, 設(shè)鏈表頭部到環(huán)的起點的長度為m, 環(huán)的長度為n,相遇的位 置與起點位置距離為k。
則可以得到:
i = m + a * n + k
其中a為慢指針走的圈數(shù)。
根據(jù)快指針和慢指針的速度關(guān)系,我們可以得到另一個式子:
2 * i = m + b * n + k
其中b為快指針走的圈數(shù)。
簡單處理得到:
i = (b - a) * n
也就是說i是圈長的整數(shù)倍。
這時將其中一個節(jié)點放到起點,然后同時向前走m步時,此時從頭部走的指針在m位置。而從相遇位置開始走的指針應(yīng)該在距離起點i + m, i為圈長整數(shù)倍,則該指針也應(yīng)該在距離起點為m的位置,即環(huán)的起點。
參考
- Floyd判圈算法
- Floyd判圈算法
- Floyd判圈算法(龜兔賽跑算法)
總結(jié)
以上是生活随笔為你收集整理的快慢指针:141. 环形链表(判断是否存在环路)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 笔记本电脑清灰有多重要笔记本电脑清灰好处
- 下一篇: 算法设计与分析:(二)动态规划