zl程序教程

您现在的位置是:首页 >  其他

当前栏目

漫画:如何找到链表的倒数第n个结点?

2023-03-15 22:09:50 时间

 

 

————— 第二天 —————

 

什么意思呢?我们以下面这个链表为例:

 

给定链表的头结点,但并不知道链表的实际长度,要求我们找到链表的倒数第n个结点。

假设n=3,那么要寻找的结点就是元素1:

 

如何利用队列呢?小灰的思路如下:

1.创建一个长度为n的队列,遍历原始链表,让结点逐一进入队列:

 

2.当队列已满时,让队尾元素出队,新结点入队:

 

3.当链表全部结点遍历完毕时,队尾的元素就是倒数第n个结点(因为队列长度是n):

 

————————————

 

首先,我们创建两个指针P1和P2,P1指向链表的头结点,P2指向链表的正数第n个结点(也就是例子中的第3个结点):

 

接下来,我们让指针P1和P2同时循环右移,每次右移一步,直到指针P2移动到链表的末尾:

 

此时,由于P2指向链表的尾结点,且P1和P2的距离是n-1,因此P1所指的结点就是我们要寻找的链表倒数第n个结点:

 

显然,这个方法从头到尾只需要对链表做一次遍历,而且仅仅使用了两个指针,算法的空间复杂度是O(1)。

 

 

  1. public class NthFromEnd { 
  2.     public static Node findNthFromEnd(Node head, int n){ 
  3.         Node p1 = head; 
  4.         Node p2 = head; 
  5.         //把p2指针移动到正数第n个结点 
  6.         for(int i=1; i<n; i++){ 
  7.             p2 = p2.next
  8.             if(p2 == null){ 
  9.                 throw new IllegalArgumentException("参数n超出链表长度!"); 
  10.             } 
  11.         } 
  12.         //p1和p2一起右移,直到p2指向链表尾结点 
  13.         while (p2.next != null){ 
  14.             p1 = p1.next
  15.             p2 = p2.next
  16.         } 
  17.         return p1; 
  18.     } 
  19.  
  20.     //快速创建链表 
  21.     private static Node buildLinkList(int[] array){ 
  22.         Node head = new Node(array[0]); 
  23.         Node p = head; 
  24.         for(int i=1; i<array.length; i++){ 
  25.             p.next = new Node(array[i]); 
  26.             p = p.next
  27.         } 
  28.         return head; 
  29.     } 
  30.  
  31.     //链表节点 
  32.     private static class Node { 
  33.         int data; 
  34.         Node next
  35.  
  36.         Node(int data) { 
  37.             this.data = data; 
  38.         } 
  39.     } 
  40.  
  41.     public static void main(String[] args) { 
  42.         int[] inputs = {5,3,7,2,4,1,9,8}; 
  43.         Node head = buildLinkList(inputs); 
  44.         Node node = findNthFromEnd(head,3); 
  45.         System.out.println("链表倒数第3个元素是:" + node.data); 
  46.     } 
  47.  

本文转载自微信公众号「程序员小灰」,可以通过以下二维码关注。转载本文请联系程序员小灰公众号。