题目
原文:
Implement an algorithm to find the nth to last element of a singly linked list.
译文:
实现一个算法从一个单链表中返回倒数第n个元素。
解答
这道题的考点在于我们怎么在一个单链表中找到倒数第n个元素? 由于是单链表,所以我们没办法从最后一个元素数起,然后数n个得到答案。 但这种最直观的思路显然是没错的,那我们有没有办法通过别的方式,从最后的元素数起数 n个来得到我们想要的答案呢。
这个次序颠倒的思路可以让我们联想到一种数据结构:栈。
我们如果遍历一遍单链表,将其中的元素压栈,然后再将元素一一出栈。那么, 第n个出栈的元素就是我们想要的。
那我们是不是需要显式地用栈这么一个结构来做这个问题呢?答案是否。看到栈,我们应当 要想到递归,它是一种天然使用栈的方式。所以,第一种解决方案用递归,让栈自己帮我 们从链表的最后一个元素数起。
思路很简单,如果指向链表的指针还未空,就不断递归。当指针为空时开始退递归,这个过 程n不断减1,直接等于1,即可把栈中当前的元素取出。
最佳实现:
维持两个指针,第一个遍历了n个元素之后,第二个开始与第一个一起遍历。当第一个指针到尾部时,第二个正好指向倒数第n个。
package cha2; public class B022 { static class Node { int value; Node next; public Node() { value = -1; next = null; } public Node(int value, Node next) { this.value = value; this.next = next; } } public static Node theLastN(Node root , int n) { Node p, q; p = root; q = root; for (int i=0; i<n; i++) { if (p == null) return null; p = p.next; } while (p != null) { p = p.next; q = q.next; } return q; } public static void main(String[] args) { Node root; Node tmp = null; for (int i=10; i>0; i--) { Node tn = new Node(i, tmp); tmp = tn; } root = tmp; tmp = theLastN(root, 10); System.out.println(tmp.value); } }