问题陈述:给定一个循环链表,实现一个在循环开始时返回节点的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;
}
答案 0 :(得分:6)
您的解决方案为O(n^2)
时间(contains()
中ArrayList
O(n)
时间O(n)
}和nodeStorage
空间(用于存储O(n)
),而#34;更复杂&#34;解决方案是O(1)
时间和O(n)
空间。
本书为感兴趣的人提供了以下解决方案,即O(1)
时间和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;
}
空间:
如果我们移动两个指针,一个速度为1,另一个速度为2, 如果链表有一个循环,它们将结束会议。为什么?认为 大约两辆汽车在赛道上行驶 - 速度更快的汽车将永远通过 慢一点!这里棘手的部分是找到循环的开始。 想象一下,作为一个类比,两个人围着一个赛道跑,一个跑 比另一个快两倍。如果他们在同一个地方开始,那么 他们下次会见吗?接下来他们将在下一圈开始时见面。 现在,让我们假设Fast Runner在n上有一个k米的起点 一圈。他们什么时候下次见面?他们将在之前达到k米 下一圈的开始。 (为什么?快跑者会做出k + 2(n - k) 步骤,包括它的开头,慢跑者会做n - k 脚步。在循环开始之前,两者都将是k步。)现在,继续 回到问题,当Fast Runner(n2)和Slow Runner(n1)是 在我们的循环链表中移动,n2将有一个良好的开端 n1进入时的循环。具体来说,它将以k为首, 其中k是循环之前的节点数。由于n2有头 k个节点的开始,n1和n2将在开始之前满足k个节点 环。所以,我们现在知道以下内容: 1. Head是来自LoopStart的k个节点(根据定义)。 2. MeetingPoint for n1和n2是来自LoopStart的k个节点(如上所示)。因此,如果我们将n1移回Head并在MeetingPoint保持n2, 并以相同的速度移动它们,它们将在LoopStart会面。
{{1}}
答案 1 :(得分:0)
amit给出了解决方案。问题是你要么知道要么不知道,但是你不能在面试中弄明白。由于我从不需要在链表中找到一个循环,除了通过面试之外,了解它对我来说毫无意义。所以对于面试官来说,这是一个面试问题,并期待amir的回答(这很好,因为它有线性时间和零额外空间),这是非常愚蠢的。
所以你的解决方案很好,除了你应该使用哈希表,你必须确保哈希表哈希对节点的引用而不是节点。假设您有一个包含字符串的节点和一个&#34; next&#34;如果字符串相等,则指针和散列函数散列字符串并将节点比较为相等。在这种情况下,除非您小心,否则您将找到第一个带有重复字符串的节点,而不是循环开始时的节点。
(amir的解决方案在语言中有一个非常类似的问题,其中==比较对象,而不是引用。例如在Swift中,你必须使用===(比较引用)和不是==(比较对象))。
答案 2 :(得分:0)