早上起来做一个算法题,题目是从尾到头输出链表。
先遍历的后输出,与栈的先进后出特性一样,所以考虑用压栈出栈来解决。
先用非递归算法,比较简单,代码如下;
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
// 方法一:非递归,利用栈先进后出的特性
ArrayList <Integer>resultArrayList = new ArrayList();// 存储结果的链表
//Stack错误地继承自Vector,导致可以通过位置来访问Stack类元素.
//而Deque拥有更好的一致性,定义了一系列fetch/add/remove/iterate的操作,而不会暴露其中的元素
Deque<Integer>stack = new ArrayDeque();
while(listNode != null){
stack.push(listNode.val);
listNode = listNode.next;
}
while(!stack.isEmpty()){
resultArrayList.add(stack.pop());
}
return resultArrayList;
}
这里要注意deque和stack的区别,本人不是做Java的,详细的请参考http://blog.csdn.net/superit401/article/details/52224702
再考虑递归算法和栈的关系,递归实际上也是一个栈结构。
一次函数调用,首先进行的操作就是讲 函数的实参和返回地址压栈。而递归的含义是函数自身调用自身,递归之所以能够实现,就是每次入栈的时候, 每次调用函数的时候,都会将形参和局部变量进行拷贝,这些东西和函数的运行无关。
具体而言,函数每次调用的时候,会完成下面三件事:
1、将所有的实参、返回地址等信息传递给被调函数保存。
2、为被调函数的局部变量分配存储区。
3、将控制转移到被调函数入口。
第二点就保证了局部变量的存储和函数运行无关,保证了递归可以顺利实现。
此问题的递归实现代码如下:
public class Solution {
ArrayList<Integer> arrayList=new ArrayList<Integer>();
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
if(listNode!=null){
this.printListFromTailToHead(listNode.next);
arrayList.add(listNode.val);
}
return arrayList;
}
}