题目描述
输入链表的第一个节点,从尾到头反过来打印出每个结点的值。
链表节点定义如下:
public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } ListNode(){} }
测试用例
- 功能测试(输入的链表有多个节点;输入的链表只有一个节点)。
- 特殊输入测试(输入的链表头节点为空)
题目考点
- 考查应聘者对单向链表的理解和编程能力。
- 考查应聘者对循环、递归和栈3个相互关联的概念的理解。
解题思路
使用头插法将链表反转
当链表反转过后,每个节点的值就可以从头到尾输出了。
PS: 在面试中,如果我们打算修改输入的数据,则最好先问面试官是否允许修改。
使用栈
每经过一个节点的时候,把该节点放到栈中。当遍历完整个链表后,再从栈顶开始逐个输出节点的值。
使用递归
递归在本质上就是一个栈结构。 我们每次访问到一个节点,先递归输入它后面的节点,在输入该节点本身。
PS: 当链表非常长的时候,就会导致函数的层级很深,从而有可能导致栈溢出。
使用 Collections.reverse()
从头到尾遍历链表,每次访问到一个节点,将值取出放入ArrayList,然后利用Collections.reverse()将数组的值反转。
package com.offer._6;
import java.util.ArrayList;
import java.util.Stack;
/**
* 从尾到头打印链表
* @author :jhys
* @date :Created in 2020/11/12 21:43
* @Description :
*/
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
//使用 栈 这种数据结构
Stack<Integer> stack = new Stack<>();
//将链表元素全部存放在 栈 里面
while (listNode != null) {
stack.add(listNode.val);
listNode = listNode.next;
}
ArrayList<Integer> ret = new ArrayList<>();
//取出栈里面的元素
while (!stack.isEmpty())
ret.add(stack.pop());
return ret;
}
}
/**
* 栈的本质就是递归,我们每访问一个节点的时候,先递归输出它后面的节点,再输出该节点本身
*/
class Solution1 {
ArrayList<Integer> arraylist=new ArrayList<Integer>();
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
if (listNode != null) {
if (listNode.next != null) {
printListFromTailToHead(listNode.next);
}
arraylist.add(listNode.val);
}
return arraylist;
}
}
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
ListNode(){}
}