如何检测链表中是存在循环
鏈表在面試中出現(xiàn)的頻率很高,有的比較正常,考鏈表的常規(guī)操作,主要看基本功是否扎實(shí),有些就比較難,難在思維的改變和是否能夠想到對(duì)應(yīng)的點(diǎn)。這里出現(xiàn)的是其中一個(gè)題目,我稱之為有環(huán)鏈表問(wèn)題。也就是從判斷一個(gè)單鏈表是否存在循環(huán)而擴(kuò)展衍生的問(wèn)題。下面來(lái)看問(wèn)題如何解決。
首先來(lái)看最基本的這個(gè)問(wèn)題:如何判斷一個(gè)單鏈表是否存在循環(huán),鏈表數(shù)目未知。算法不能破壞鏈表。
思路一:哈希表法
將所有的遍歷過(guò)的節(jié)點(diǎn)用哈希表存儲(chǔ)起來(lái),用節(jié)點(diǎn)的內(nèi)存地址作為哈希表的值存儲(chǔ)起來(lái)。每遍歷一個(gè)節(jié)點(diǎn),都在這個(gè)結(jié)構(gòu)中查找是否遍歷過(guò)。如果找到有重復(fù),則說(shuō)明該鏈表存在循環(huán)。如果直到遍歷結(jié)束,則說(shuō)明鏈表不存在循環(huán)。哈希表中存儲(chǔ)的值為節(jié)點(diǎn)的內(nèi)存地址,這樣查找的操作所需時(shí)間為O(1),遍歷操作需要O(n),hash表的存儲(chǔ)空間需要額外的O(n)。所以整個(gè)算法的時(shí)間復(fù)雜度為O(n),空間復(fù)雜度為O(n)。
思路二:反轉(zhuǎn)指針?lè)?/strong>
這種比較特別,是使用反轉(zhuǎn)指針的方法,每過(guò)一個(gè)節(jié)點(diǎn)就把該節(jié)點(diǎn)的指針?lè)聪?。?dāng)有環(huán)的時(shí)候,最后指針會(huì)定位到鏈表的頭部,如果到最后,都沒(méi)有再到頭部,那說(shuō)明鏈表不存在循環(huán)。這個(gè)方法會(huì)破壞掉鏈表,所以如果要求是不能破壞鏈表的話,我們最后就還需要反轉(zhuǎn)一下,再將鏈表恢復(fù)(題目說(shuō)不能破壞環(huán),那我破壞之后恢復(fù)原樣也算沒(méi)破壞環(huán)呀。哈哈,思路不要被局限住了)。這個(gè)方法使用的空間復(fù)雜度為O(1),其實(shí)是使用了3個(gè)指針,用于進(jìn)行反轉(zhuǎn)。同時(shí),時(shí)間復(fù)雜度為O(n)。
思路三:快慢指針(是錯(cuò)的!)
首先我們要理解什么是快慢指針??熘羔榩f(f就是fast的縮寫(xiě))每次移動(dòng)2個(gè)節(jié)點(diǎn),慢指針ps(s為slow的縮寫(xiě))每次移動(dòng)1個(gè)節(jié)點(diǎn),如果快指針能夠追上慢指針,那就說(shuō)明其中有一個(gè)環(huán),否則不存在環(huán)。
這個(gè)方法的時(shí)間復(fù)雜度為O(n),空間復(fù)雜度為O(1),實(shí)際使用兩個(gè)指針。
想像一種情況,當(dāng)快指針走到一個(gè)環(huán)的時(shí)候,慢指針還離快指針很遠(yuǎn),甚至當(dāng)快指針走出環(huán)的時(shí)候慢指針還沒(méi)到達(dá)環(huán),這時(shí)候快指針永遠(yuǎn)不會(huì)追上慢指針。所以快慢指針無(wú)法解決鏈表存在循環(huán)的問(wèn)題,快慢指針能解決的只是鏈表存在環(huán)的問(wèn)題,也就是這個(gè)循環(huán)在鏈表尾部??梢哉f(shuō)鏈表存在環(huán)是鏈表存在循環(huán)的一種特殊情況。
轉(zhuǎn)載于:https://www.cnblogs.com/chanshuyi/p/5314391.html
總結(jié)
以上是生活随笔為你收集整理的如何检测链表中是存在循环的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: SpringBoot 配置文件 appl
- 下一篇: iOS技术周报-第28期