从尾到头打印链表
题目描述
输入链表的第一个节点,从尾到头反过来打印出每个结点的值。
解题思路
使用栈
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<Integer> stack = new Stack<Integer>();
ArrayList<Integer> arr = new ArrayList<Integer>();
while(listNode != null){
stack.add(listNode.val);
listNode = listNode.next;
}
while(!stack.isEmpty()){
arr.add(stack.pop());
}
return arr;
}
}
使用递归
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> arr = new ArrayList<Integer>();
if(listNode != null){
arr.addAll(printListFromTailToHead(listNode.next));
arr.add(listNode.val);
}
return arr; //每次层返回的arr事添加的重点 最后返回给arr.addAll的内容,首次返回null
}
}
add是将传入的参数作为当前List中的一个Item存储,即使你传入一个List也只会另当前的List增加1个元素
addAll是传入一个List,将此List中的所有元素加入到当前List中,也就是当前List会增加的元素个数为传入的List的大小
使用头插法
利用链表头插法为逆序的特点。
头结点和第一个节点的区别:
- 头结点是在头插法中使用的一个额外节点,这个节点不存储值;
- 第一个节点就是链表的第一个真正存储值的节点。
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
// 头插法构建逆序链表
ListNode head = new ListNode(-1);
while (listNode != null) {
ListNode memo = listNode.next;
listNode.next = head.next;
head.next = listNode;
listNode = memo;
}
// 构建 ArrayList
ArrayList<Integer> ret = new ArrayList<>();
head = head.next;
while (head != null) {
ret.add(head.val);
head = head.next;
}
return ret;
}
尾插法
while (listNode != null) {
ListNode m = listNode.next;
listNode.next = head.next;
head.next = listNode;
head = listNode;
listNode = m;
头插法尾插法详解:
https://blog.csdn.net/taotao_521/article/details/79170791
使用 Collections.reverse()
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> ret = new ArrayList<>();
while (listNode != null) {
ret.add(listNode.val);
listNode = listNode.next;
}
Collections.reverse(ret);
return ret;
}
参考资料: