[英]Cracking the Coding Interview, 6th edition, 2.8
問題陳述:給定一個循環鏈表,實現一個在循環開始時返回節點的algoirthm。
答案密鑰提供了比我建議的更復雜的解決方案。 我有什么問題?:
public static Node loopDetection(Node n1) {
ArrayList<Node> nodeStorage = new ArrayList<Node>();
while (n1.next != null) {
nodeStorage.add(n1);
if (nodeStorage.contains(n1.next)) {
return n1;
}
else {
n1 = n1.next;
}
}
return null;
}
你的解決方案是O(n^2)
時間( ArrayList
每個contains()
是O(n)
時間)和O(n)
空間(用於存儲nodeStorage
),而“更復雜”的解決方案是O(n)
時間和O(1)
空間。
本書為感興趣的人提供了以下解決方案,即O(n)
時間和O(1)
空間:
如果我們移動兩個指針,一個速度為1,另一個速度為2,如果鏈表有循環,它們將會結束。 為什么? 想想兩輛在賽道上行駛的汽車 - 速度越快的汽車總會越過越慢! 這里棘手的部分是找到循環的開始。 想象一下,作為一個類比,兩個人在賽道上比賽,一個賽跑的速度是另一個賽車的兩倍。 如果他們在同一個地方開始,他們下一次會什么時候見面? 接下來他們將在下一圈開始時見面。 現在,讓我們假設Fast Runner在n步圈上有一個k米的起跑線。 他們什么時候下次見面? 他們將在下一圈開始前達到k米。 (為什么?快跑者會做出k + 2(n-k)步,包括它的頭部開始,慢跑者會做n-k步。兩者都將在循環開始之前的k步。)現在,去回到問題,當Fast Runner(n2)和Slow Runner(n1)在我們的循環鏈表中移動時,當n1進入時,n2將在循環上有一個開頭。 具體來說,它將具有k的頭部起點,其中k是循環之前的節點數。 由於n2具有k個節點的頭部起始,因此n1和n2將在循環開始之前與k個節點相遇。 因此,我們現在知道以下內容:1。Head是來自LoopStart的k個節點(根據定義)。 2. MeetingPoint for n1和n2是來自LoopStart的k個節點(如上所示)。 因此,如果我們將n1移回Head並在MeetingPoint保持n2,並以相同的速度移動它們,它們將在LoopStart上相遇。
LinkedListNode FindBeginning(LinkedListNode head) {
LinkedListNode n1 = head;
LinkedListNode n2 = head;
// Find meeting point
while (n2.next != null) {
n1 = n1.next;
n2 = n2.next.next;
if (n1 == n2) {
break;
}
}
// Error check - there is no meeting point, and therefore no loop
if (n2.next == null) {
return null;
}
/* Move n1 to Head. Keep n2 at Meeting Point. Each are k steps
/* from the Loop Start. If they move at the same pace, they must
* meet at Loop Start. */
n1 = head;
while (n1 != n2) {
n1 = n1.next;
n2 = n2.next;
}
// Now n2 points to the start of the loop.
return n2;
}
amit給出了解決方案。 問題是你要么知道要么你不知道,但你不能在面試中弄明白。 由於我從來沒有需要在鏈表中找到一個循環,除了通過面試之外,了解它對我來說毫無意義。 所以對於面試官來說,這是一個面試問題,並期待amir的回答(這很好,因為它有線性時間和零額外空間),這是非常愚蠢的。
所以你的解決方案大多沒問題,除了你應該使用哈希表,你必須確保哈希表散列對節點而不是節點的引用 。 假設您有一個包含字符串和“下一個”指針的節點,並且哈希函數對字符串進行哈希處理,並且如果字符串相等則將節點比較為相等。 在這種情況下,你會發現第一個節點有一個重復的字符串,而不是循環開始時的節點,除非你小心。
(amir的解決方案在語言中有一個非常類似的問題,其中==比較對象,而不是引用。例如在Swift中,你必須使用===(比較引用)而不是==(比較對象))。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.