Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.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 在单链接列表-算法中查找最后三个元素_Java_Algorithm_Linked List - Fatal编程技术网

Java 在单链接列表-算法中查找最后三个元素

Java 在单链接列表-算法中查找最后三个元素,java,algorithm,linked-list,Java,Algorithm,Linked List,我正在考虑使用Algo算法来查找单链接列表中的最后三个元素,然后我自己找到了一个(空间效率) 使用O(n)时间复杂度[大量空间复杂度]的循环将链接列表放入ArrayList中 然后找到Arraylist的大小,并在(size-2)索引位置检索元素[required element] 如果我的算法有意义,请指导我 供参考 我搜索的其他内容是: 放置两个指针,将第一个指针保持在第一个元素上,将第二个指针保持在第三个元素上,并将它们平行移动 当第二个指针到达链接列表的末尾时,检索由第一个指针指向的节点

我正在考虑使用Algo算法来查找单链接列表中的最后三个元素,然后我自己找到了一个(空间效率)
使用O(n)时间复杂度[大量空间复杂度]的循环将链接列表放入ArrayList中
然后找到Arraylist的大小,并在(size-2)索引位置检索元素[required element] 如果我的算法有意义,请指导我

供参考
我搜索的其他内容是: 放置两个指针,将第一个指针保持在第一个元素上,将第二个指针保持在第三个元素上,并将它们平行移动

当第二个指针到达链接列表的末尾时,检索由第一个指针指向的节点[必需的节点]

由于链接列表是单独链接的,您需要从头到尾遍历它以了解第三个到最后一个元素是什么,os
O(n)
时间是不可避免的(除非保持指向链接列表中倒数第三个元素的指针)


您的双指针想法将使用常量空间。这可能是更好的选择,因为创建ArrayList将有更多的开销,并使用更多的空间。

由于链表是单独链接的,您需要从头到尾遍历它以了解从第三个到最后一个元素是什么,时间是不可避免的(除非保持指向链接列表中倒数第三个元素的指针)

您的两个指针想法将使用常量空间。这可能是更好的选择,因为创建ArrayList将有更多开销,并使用更多空间。

获取两个指针。pA,pB 将pA移动到3个元素,将pB移动到头部:

1->2->3->4-> .... ->99->100 
|     |
pB    pA
在此之后,在同一个循环中移动两个指针,直到pA到达最后一个元素

此时pB将指向最后的第三个元素

1->2->3->4-> .... ->98->99->100 
                    |        |
                    pB       pA
编辑: 遍历将是一个:

while(pA->next!=null){
   pA = pA->next;
   pB = pB->next;
}
这里pB将是最后三个

获取两个指针。pA,pB 将pA移动到3个元素,将pB移动到头部:

1->2->3->4-> .... ->99->100 
|     |
pB    pA
在此之后,在同一个循环中移动两个指针,直到pA到达最后一个元素

此时pB将指向最后的第三个元素

1->2->3->4-> .... ->98->99->100 
                    |        |
                    pB       pA
编辑: 遍历将是一个:

while(pA->next!=null){
   pA = pA->next;
   pB = pB->next;
}
这里pB将是最后三个

  • 使用两个指针:
    pointer-1
    pointer-2
  • 使
    指针-1
    指向单链表中的第三个节点

     pointer-1 = node1->next->next; // point to 3rd nd
    
     node1-->node2-->node3-->node4---> ...... -->node-last
                     ^
                     |
                    pointer-1
    
  • 现在将指针2设置为指向第一个节点

     pointer-2 = node1;   // point to 1st nd
    
     node1-->node2-->node3-->node4---> ...... -->node-last
       ^              ^
       |              |
      pointer-2      pointer-1
    
  • 现在,在链表中循环移动,直到
    pointer-1
    指向最后一个节点,在循环中还更新pointer-2(每次指向自身的下一个节点)

它以O(n)次工作,其中
n
是链表中的节点数。

  • 使用两个指针:
    pointer-1
    pointer-2
  • 使
    指针-1
    指向单链表中的第三个节点

     pointer-1 = node1->next->next; // point to 3rd nd
    
     node1-->node2-->node3-->node4---> ...... -->node-last
                     ^
                     |
                    pointer-1
    
  • 现在将指针2设置为指向第一个节点

     pointer-2 = node1;   // point to 1st nd
    
     node1-->node2-->node3-->node4---> ...... -->node-last
       ^              ^
       |              |
      pointer-2      pointer-1
    
  • 现在,在链表中循环移动,直到
    pointer-1
    指向最后一个节点,在循环中还更新pointer-2(每次指向自身的下一个节点)


它以O(n)次工作,其中
n
是链表中的节点数。

解决此问题的另一种视图,即使是O(n)

创建一个空数组(n),从0开始指向此数组的指针,也从链表的开头开始。每次访问节点时,将其存储在数组的当前索引中,并前进数组指针。继续填充数组中的节点,当到达数组末尾时,请重新从开头开始,以便覆盖。
现在,一旦您结束列表的最后一个端点,指针n elemtn from end:)

即使是O(n),也可以使用另一个视图来解决此问题

创建一个空数组(n),从0开始指向此数组的指针,也从链表的开头开始。每次访问节点时,将其存储在数组的当前索引中,并前进数组指针。继续填充数组中的节点,当到达数组末尾时,请重新从开头开始,以便覆盖。
现在,一旦您结束了列表的最后一个结尾,指针n elemtn from end:)

实际上,Java
LinkedList会跟踪其大小,因此您可以直接转到“list.get(list.size()-2)”,但对于构造的链表,我会执行以下操作:


保留一个包含3个值的数组。在遍历列表时,在
数组[i%3]
处添加更新值。当没有更多的值时,返回
array[(i-2)%3]

在实践中,Java
LinkedList
会跟踪其大小,因此您可以直接转到“list.get(list.size()-2)”,但对于构造的链接列表,我会执行以下操作:


保留一个包含3个值的数组。在遍历列表时,在
数组[i%3]
处添加更新值。当没有更多的值时,返回
数组[(i-2)%3]

处的值。我要做的第一件事是要求您重新考虑使用单链接列表。为什么不将数据存储在ArrayList中?它能做你想做的一切,而且它是一个内置的,所以与大多数人会写的东西相比,它相对高效

如果您被绑定并决定使用链表,我建议保留一个指向最后三个元素(tle)的直接指针。插入是很容易的-如果它们出现在tle之前,什么也不做;如果在之后,将tle指针前进到tle的下一个。删除更麻烦,但可能不是大多数时候。如果移除发生在tle之前,仍然是tle。令人恼火的情况是,如果要删除的元素是tle或更高版本,在这种情况下,您需要从头开始迭代,直到当前节点的下一个()引用是tle。当前节点将成为新的tle,然后可以继续删除。由于只有三个节点调用这一级别的工作,因此如果列表为