题目描述
- 输入一个链表,从尾到头打印链表每个节点的值。
- 地址:牛客链接
解决方法
- 个人认为这是一个非常*的题,最后竟然让你返回一个list
- 方法一:利用栈 LIFO 的特点,先遍历链表,存入栈,然后弹栈进入list,即完成反转。但是这样用到了额外空间。
- 方法二:递归。先反转当前节点之后的元素,将反转后的存入list(这便是递归调用),然后将当前节点的加入list中。
- 方法三:在原链表进行原地反转,然后遍历反转后的链表,加入list中。没有用到额外空间
经验教训
- 链表题解题两大方向不能忘
- 递归究竟是如何想出来的,如何缩小问题规模的,如何设置base case的
- 另外,这题的递归实现非常有意思,将list设置成了一个全局变量,避免了传参,非常机智的做法。要看一看具体实现。
代码实现
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> list = new ArrayList<>();
if (listNode == null) {
return list;
}
Stack<Integer> stack = new Stack<>();
while (listNode != null) {
stack.push(listNode.val);
listNode = listNode.next;
}
while (! stack.empty()) {
list.add(stack.pop());
}
return list;
}
ArrayList<Integer> list = new ArrayList<>();
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
if (listNode == null) {
return list;
}
printListFromTailToHead(listNode.next);
list.add(listNode.val);
return list;
}
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> list = new ArrayList<>();
if (listNode == null ) {
return list;
}
ListNode preNode = null;
ListNode curNode = listNode;
ListNode nextNode = null;
while (curNode != null) {
nextNode = curNode.next;
curNode.next = preNode;
preNode = curNode;
curNode = nextNode;
}
while (preNode != null) {
list.add(preNode.val);
preNode = preNode.next;
}
return list;
}