有乙個單向鍊錶,鏈中可能有「環」,如何用程式判斷呢?
方法1(最低效)
最常想到的是:首先從頭結點開始遍歷整個鍊錶,每遍歷乙個,就和之前遍歷過的比較,,,
這相當於每次遍歷了兩遍,無疑是擴大了鍊錶「遍歷」帶來的劣勢,其時間複雜度為o(n^2),由於沒有額外的儲存空間,故空間複雜度為o(1)。
這也太低效了吧。
方法2(次之)
首先建立乙個以節點id為key的hashset集合,用來儲存曾經遍歷過的節點。
這種方式相當於「用空間換時間」,其使用額外的儲存空間來代替重複遍歷鍊錶帶來的時間上的「低效」。
時間複雜度o(n),但空間複雜度也是o(n)。
雙指標法!
正如我前文所說,雙指標法在諸如鍊錶等的演算法中簡直是游刃有餘。
首先建立兩個指標p1和p2,讓他們同時指向這個鍊錶的頭結點。然後開始乙個大迴圈,在迴圈體中,讓p1每次向後移動乙個節點,而p2每次移動兩個節點,然後比較兩個指標所指向節點是否相等,如果相等,則鍊錶有環!
bool i***istloop(listnode* phead)
//到達末尾仍然沒有相遇,則不存在環
return false ;
}
思路解讀:(1)定義兩個指標分別為 slow,fast,並且將指標均指向煉表頭節點。
(2)規定,slow 指標每次前進 1 個節點,fast 指標每次前進兩個節點。
(3)當 slow 與 fast 相等,且二者均不為空,則鍊錶存在環。
若煉表中存在環,則快慢指標必然能在環中相遇。這就好比在環形跑道中進行龜兔賽跑。由於兔子速度大於烏龜速度,則必然會出現兔子與烏龜再次相遇情況。因此,當出現快慢指標相等,且二者不為null時(即二者不在尾節點處相遇),則表明鍊錶存在環。
如何求出入環節點?
上面我們判斷了是否有環,那麼,在有環處一定兩指標是相遇的。
因為快慢指標的性質,我們知道,快指標比慢指標快一步:這樣,當兩者再次相遇時,p2比p1整整多走了一圈。
也就是說,從煉表頭到入環節點的位置,恰等於從首次相遇點回到入環點的距離!
我們把p1放在相遇位置,把p2放在頭結點位置,這次,讓他們以相同步率移動,則再次相遇的節點,就是要求的「入環節點」!
騰訊面試題 判斷鍊錶是否有環
目錄前言 1.快慢指標 2.雜湊表法 參考資料點這裡。用兩個指標指向煉表頭,每次迴圈,快指標往前兩步,慢指標往前一步 在迴圈過程中,如果快指標等於慢指標 相遇 則表示鍊錶有環 否則不存在環。如下 public boolean findbeginloop listnode head return fa...
面試題之 鍊錶是否有環
leetcode面試題 以上面這個鍊錶為例,鍊錶 現了環路,但是如何檢測出該鍊錶是否含有環路呢?使用兩個指標,乙個快指標和乙個慢指標,使用快指標追趕慢指標,當兩個指標相遇,那麼證明該鍊錶中存在環路。追趕理論 當兩個人在乙個環形跑道上跑步時,只要其中乙個人的速度比另乙個人的速度快,那麼只要給足夠多的時...
華為面試題 怎麼判斷鍊錶中是否有環?????
定義兩個指標,一前一後,同時移動,前面的移動比後面的慢,如果是迴圈的則後面的肯定會追上前面的 思路就是弄兩個指標,開始指向不同的鍊錶不同的位置,然後1個指標移動間隔是1,乙個指標移動間隔是2,如果快的能追上慢的,那說明就有環了。就如何兩個人繞圈跑步,速度不一樣,如果速度快的能追上慢的,那說明跑道是環...