推断单向链表中是否有环和查找环的入口
快慢指針
算法描寫(xiě)敘述
定義兩個(gè)指針slow, fast。
slow指針一次走1個(gè)結(jié)點(diǎn),fast指針一次走2個(gè)結(jié)點(diǎn)。假設(shè)鏈表中有環(huán),那么慢指針一定會(huì)再某一個(gè)時(shí)刻追上快指針(slow == fast)。假設(shè)沒(méi)有環(huán),則快指針會(huì)第一個(gè)走到NULL。
實(shí)現(xiàn)
結(jié)點(diǎn)定義例如以下:
class Node {public Node next;public Object data;public static int sequence = 0; }算法:
/*** 快慢指針* @param head* @return*/public static boolean checkCircle(Node head) {Node fast = null;Node slow = null;fast = head;slow = head;while (true) {// 慢指針移動(dòng)一步if (null != slow.next) {slow = slow.next;} else {return false;}// 快指針移動(dòng)兩步if (null != fast.next && null != fast.next.next) {fast = fast.next.next;} else {return false;}// 檢查是否相遇if (slow == fast) {return true;}}}步數(shù)檢查
算法描寫(xiě)敘述
上面的算法僅僅能推斷鏈表中有沒(méi)有環(huán),假設(shè)我們想找出環(huán)的入口怎么辦呢?
定義兩個(gè)指針p, q。p每走一個(gè)結(jié)點(diǎn)(即一步),q則從頭一直向后走,直到q走到NULL或p, q走到同一個(gè)結(jié)點(diǎn)但走過(guò)的步數(shù)不同樣為止。
此時(shí)q的步數(shù)就是環(huán)入口在結(jié)點(diǎn)中的位置。假設(shè)走到NULL則說(shuō)明鏈表不存在環(huán)。
為什么p, q走到同一個(gè)結(jié)點(diǎn)但步數(shù)不相等時(shí)就說(shuō)明有環(huán)呢?由于假設(shè)p, q步數(shù)同樣,說(shuō)明它們走過(guò)的結(jié)點(diǎn)是一樣的,假設(shè)p, q步數(shù)不同了。則說(shuō)明p是從環(huán)里走了一圈又回到了環(huán)的入口。此時(shí)q到達(dá)該結(jié)點(diǎn)時(shí)還沒(méi)有走過(guò)環(huán),因此步數(shù)不相等,并且此時(shí)q的步數(shù)就是環(huán)的入口。
實(shí)現(xiàn)
/*** 查找環(huán)的起點(diǎn)* @param head* @return 返回元素的索引,從0開(kāi)始。沒(méi)有找到返回-1*/public static int findCircleEntry(Node head) {Node p = head; // 總是從頭開(kāi)始Node q = head;int pSteps = 0;int qSteps = 0;while (null != q.next) {q = q.next;++qSteps;// p從頭開(kāi)始走while (null != p.next) {p = p.next;++pSteps;// 當(dāng)p與q指向同一個(gè)結(jié)點(diǎn)時(shí)if (p == q) {// 假設(shè)走的步數(shù)不同,則這就是入口if (pSteps != qSteps) {return pSteps - 1;} else {// 走的步數(shù)同樣,不是入口break;}}}p = head; // 回到頭結(jié)點(diǎn)pSteps = 0;}// 當(dāng)中有一個(gè)指針走到了頭,說(shuō)明沒(méi)有環(huán)return -1;}總結(jié)
以上是生活随笔為你收集整理的推断单向链表中是否有环和查找环的入口的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python的内建模块itertools
- 下一篇: synchronized的4种用法