1. 程式人生 > >環形連結串列(leetcode簡單篇一百四十一題)

環形連結串列(leetcode簡單篇一百四十一題)

給定一個連結串列,判斷連結串列中是否有環

拿到這道題其實我相信很多同學已經看過官方的解答了

快慢指標法:在返回單鏈表的中間節點其實我們就已經使用過這個辦法了,讓fast指標一次走倆步,讓slow指標一次走一步。你可以假想倆個人同時在操場上跑步,快的那個人假設一直比慢的快,那麼在不久後他們肯定會相遇,於是判斷有沒有環有了下面程式碼

bool hasCycle(struct ListNode *head) {
    if(head == NULL || head -> next == NULL) return false;
    struct ListNode* slow =
head; struct ListNode* fast = head -> next; while(slow != fast) { if(fast == NULL || fast -> next == NULL) { return false; } slow = slow -> next; fast = fast -> next -> next; } return true; }

寫到這裡你可能覺得結束了,但是現在筆者反過來問你一個問題,題中的思路是讓一個指標快一個指標慢,讓快指標去追慢指標,直到相遇就跳出。那是不是慢指標一次前進一步,快指標一次前進三步四步也可以呢?

在這裡插入圖片描述

你現在可以讓環中的a一次走一步(a = a -> next)然後讓b一次走三步(b =b -> next -> next -> next),你看看他們什麼時候可以相遇。答案很明確,他是一個死迴圈。

那麼為什麼一個走一步一個人走倆步可以,你可以這樣假設,兩個指標現在相差n步,每走一次他們的距離都會-1變為n-1.最後他們相差的距離會縮短為0,而上面死迴圈假設中間的距離還有1他們每次距離縮短2,剛好跳過了0變為-1,所以沒有相遇。這裡同學們一定要注意,並不是所有的情況都適合。

ps:但是如果有同學去測試慢指標走一步快指標走三步,oj會通過,我認為這應該是用例不全面,如果有什麼不同房的看法,歡迎留言討論。