單鏈表是否有環問題
小咖是某計算機專業的學生。linglingling,伴隨這鈴聲,同學們都準時來上課了。
老師:這節課是計算機課,我們學習了單鏈表,請同學說一下什麽是單鏈表。
同學們紛紛舉起了手。好,小白你來說。
小白:單鏈表是一種線性表,它的存儲單元可以不是連續的,從頭節點開始,每個節點都有一個指針,指向下一個節點,最後一個節點指向null,頭節點不被指向。
老師:好,那麽誰來說一下鏈表的這種結構有什麽優點呢?
同學們紛紛舉起了手。好,小黃你來說。
小黃:線性表的一種,鏈式表的在存儲空間中可以是不連續的,因此存儲密度較低,還有增刪的時候只需要改變指針的指向就可以了,而不是像順序表那樣,比如你要在某個位置添加一個元素,那麽其他的元素都要向後移,因此鏈式表增刪相對較快些。
老師:好,大家掌握的不錯啊,那麽大家思考一個問題,怎麽判斷一個單鏈表是否有環。
如圖,這樣的單鏈表就是有環的鏈表。
註:數字1-10代表節點1-10,節點存儲值和指針。
老師:好,小紅同學你來說。
小紅:兩層循環,第一層循環從頭遍歷,第二層循環從頭遍歷到第一層循環當前的節點,如果存在相同的節點,那麽鏈表有環。
老師:好,這樣做確實是可以判斷是否有環,但是效率並不高,遍歷兩次時間復雜度o(n^2),由於沒有開辟額外的空間,所以空間復雜度o(1)。哪位同學還有更好的方法嗎。
老師:好,小明你來說一下。
小明:一層循環,創建一個hashset,把節點放到hashset中,如果出現相同的節點,說明單鏈表有環。
老師:好,小明同學采用了空間換時間的方法,此時的時間復雜度o(n),由於開辟了和鏈表單獨相關的n的空間,所以空間復雜度o(n)。那還有沒有更好的方法呢。
老師:誰是計算機課帶表啊。
課帶表:
老師:那麽你來說說,有什麽更好的方法。
課代表:
如果兩個人在環形的跑道上賽跑,快的人總會再次追上慢的。
因此我們可以假設用兩個指針比如兩個賽跑的同學,一個快指針,一個慢指針,我們稱為快慢指針方法。
那麽我們來說一下說它是實現思路:
快指針每次移動兩步,慢指針每次移動一步,如果兩個節點相等,則說明有環,返回true,否則返回false。
代碼實現大概是是這個樣子的。
Node fast = head;
Node slow = head;
while(fast.next != null)
{
fast = fast.next.next;
slow = slow.next;
if (slow == fast)
return true;
}
return false;
老師:非常好,這個方法的時間復雜度為o(n),空間復雜度為o(1)。請大家回去思考一個問題,如何判斷單鏈表是否有交點。下節課老師提問,同學們下課。
歡迎大家和作者一起交流技術,或者您有好的建議等等,都可以聯系作者。
感興趣的朋友可以關註公眾號,更多精彩等著您:javaxiaokashow
單鏈表是否有環問題