剑指offer-6 从尾到头打印链表
微信搜索【程序员画工师】关注更多Java编程技术、数据结构与算法、面试题相关内容。
题目
输入一个链表的头节点,从尾到头反过来打印出每个节点的值。链表节点定义如下
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
思路
要求我们将链表从后向前的顺序打印,那可以利用栈的“后进先出”的特点,采用Arraylist的线性顺序表的特性,将链表每次向后遍历的数依次插在首位,最后再顺序打印Arraylist里的元素即可。
上代码
/**
* public class ListNode {
* int val;
* ListNode next = null;
*
* ListNode(int val) {
* this.val = val;
* }
* }
*
*/
import java.util.ArrayList;
public class Solution {
public void printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
while(listNode != null){
arrayList.add(0,listNode.val);
listNode = listNode.next;
}
for(Integer i:arrayList){
System.out.println(i);
}
}
}
剑指解法
利用栈的“后进先出”的特点,用栈来实现这种顺序(上面的解法Arraylist就类似栈的作用)。每经过一个节点的时候,把该节点放到一个栈中。当遍历完整个链表的时候,再从栈顶开始逐个输出节点的值。于是又想到了用递归来实现。要实现反过来输出链表,我们每访问到一个节点的时候,先递归输出它后面的节点,再输出该节点自身。基于递归有一个问题,当链表非常长的时候,就会导致函数调用的层级很深,从而有可能导致函数调用栈溢出。显然用栈基于循环实现的代码鲁棒性要更好一些。
附剑指offer原文中解法的Java版,供读者参考。
/**
* public class ListNode {
* int val;
* ListNode next = null;
*
* ListNode(int val) {
* this.val = val;
* }
* }
*
*/
public class Solution {
public void printListFromTailToHead(ListNode listNode) {
if(listNode==null){
return result;
}
if(listNode.next!=null){
result = printListFromTailToHead(listNode.next);
}//当指针没有到链表尾节点时递归,当到达尾节点时则输出。保证了从尾到头输出链表值
System.out.println(listNode.val);
}
}
References
[1] 《剑指offer(第二版)》 何海涛著
程序员画工师公众号,欢迎交流