Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 破解编码面试,第6版,2.8_Java_Algorithm_Linked List_Big O_Time Complexity - Fatal编程技术网

Java 破解编码面试,第6版,2.8

Java 破解编码面试,第6版,2.8,java,algorithm,linked-list,big-o,time-complexity,Java,Algorithm,Linked List,Big O,Time Complexity,问题陈述:给定一个循环链表,实现一个返回循环开头节点的算法 答案键给出了比我建议的更复杂的解决方案。我的怎么了 public static Node loopDetection(Node n1) { ArrayList<Node> nodeStorage = new ArrayList<Node>(); while (n1.next != null) { nodeStorage.add(n1); if (nodeStorage.

问题陈述:给定一个循环链表,实现一个返回循环开头节点的算法

答案键给出了比我建议的更复杂的解决方案。我的怎么了

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;
}
公共静态节点循环检测(节点n1){
ArrayList NodeStoreRage=新的ArrayList();
while(n1.next!=null){
nodeStorage.add(n1);
if(nodeStorage.contains(n1.next)){
返回n1;
}
否则{
n1=n1.next;
}
}
返回null;
}
您的解决方案是
O(n^2)
时间(每个
ArrayList
中包含()
O(n)
时间)和
O(n)
空间(用于存储
nodeStorage
),而“更复杂”的解决方案是
O(n)
时间和
O(1)
空间

本书为感兴趣的人提供了以下解决方案,即
O(n)
time和
O(1)
space:

如果我们移动两个指针,一个速度为1,另一个速度为2, 如果链表有一个循环,他们将结束会议。为什么?思考 大约有两辆车在跑道上行驶,速度较快的车总是会通过跑道 慢一点!这里棘手的部分是找到循环的起点。 想象一下,作为一个类比,两个人绕着一条跑道跑,一个人在跑 比另一个快两倍。如果他们在同一地点出发,什么时候 他们下次会见面吗?他们将在下一圈开始时相遇。 现在,让我们假设快跑者在一个n上领先k米 跨步跑。他们下次什么时候见面?他们将在比赛开始前在k米处相遇 开始下一圈。(为什么?快跑者会得到k+2(n-k) 步骤,包括它的头开始,和慢跑者将作出n-k 步骤。两个步骤都是循环开始前的k个步骤。)现在,开始 回到问题上来,当快跑者(n2)和慢跑者(n1)被激活时 围绕我们的循环链接列表,n2将在 n1进入时的循环。具体来说,它将以k开头, 其中k是循环之前的节点数。因为n2有一个头部 k个节点的开始,n1和n2将在开始前与k个节点相遇 环因此,我们现在知道: 1.Head是LoopStart中的k个节点(根据定义)。 2.n1和n2的汇合点是LoopStart的k个节点(如上所示)。因此,如果我们将n1移回头部,并将n2保持在交汇点, 以同样的速度移动它们,它们将在一开始相遇


这是阿米特给出的解决方案。问题是你要么知道,要么不知道,但在面试中你无法弄清楚。因为我从来没有必要在链表中找到一个循环,知道它对我来说是毫无意义的,除了通过面试。所以对于一个面试官来说,把这当作一个面试问题来回答,并期待阿米尔的回答(这很好,因为它有线性时间和零额外空间),是相当愚蠢的

因此,您的解决方案基本上是好的,只是您应该使用哈希表,并且您必须确保哈希表对节点而不是节点的引用进行哈希。假设有一个节点包含一个字符串和一个“next”指针,哈希函数对该字符串进行哈希运算,如果字符串相等,则将节点作为相等进行比较。在这种情况下,您会找到第一个具有重复字符串的节点,而不是循环开头的节点,除非您非常小心


(阿米尔的解决方案在语言中有一个非常类似的问题,即==比较对象,而不是引用。例如,在Swift中,您必须使用===(比较引用)和not==(比较对象))。

我很难想象这个算法发生了什么。希望这能帮助其他人

在时间t=k(3)时,p2距离头部(0)的距离是p1的两倍,因此为了让它们回到直线上,我们需要p2“追赶”到p1,并且需要L-k(8)5个步骤才能发生。p2以2倍于p1的速度行驶

在时间t=k+(L-k)(8)时,p2需要向前移动k步才能回到k。如果我们将p1重置回头部(0),我们知道如果p2以与p1相同的速度行驶,p1和p2将在k(分别为3和19)处会合


您能否在回答中提供
O(n)
解决方案?@TimBiegeleisen O(n)时间和空间将只使用哈希集而不是数组列表。要获得一个恒定的时间,你需要一个书中描述的“技巧”(见编辑)@amit你的意思是在评论中保持恒定的空间吗?“恒定时间几乎肯定是不可能的。”莫伦:是的,当然是线性时间和恒定空间。但是答案本身确实正确地提到了它。在第一个
while
循环中,它不应该是
while(n2!=null和n2.next!=null)
?下面的
if
也一样。我很困惑。在循环链表中,您将保留对列表“head”的引用,head是循环中的“第一个”节点,因此它位于循环的开头,因此
返回head
(O(1))。或者,如果你唯一的参考是列表的“尾部”,则头部位于“尾部。Next”,再次是一个简单的返回语句。@安德烈亚斯:考虑一个列表A->B-> C>D>E-> C--> D -> E->…循环的起点是C,而不是A。带有循环的链表没有尾部。想象一下,在一条单行道上行驶到一个没有任何出口的环形交叉口上。@gnasher729最后一个节点指向第一个节点的a和一个带循环的损坏的非循环(也称为开放或线性)链表之间存在差异。我现在可以看到,这个问题实际上不是关于循环链表,而是关于一个损坏的线性链表,因此我最初的困惑。“问题陈述”的措辞很糟糕。你是对的,但现实是招聘人员会继续问这样的问题……正如你提到的,我提出的解决方案是使用参考资料的哈希表。我猜这个解决方案相对于书中给出的解决方案的缺点是O(n)空间vs O
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;
   }