从尾到头打印链表
题目描述
输入一个链表,按链表从尾到头的顺序返回一个ArrayList
看到这道题,很多人的第一反应是从头到尾的输出将会比较简单,于是我们很自然的想把链表中连接节点的指针反转过来,改变链表的方向,然后就可以从头到尾输出了。但该方法会改变原有链表的结构,是否允许在打印链表的时候修改链表的结构?这取决于面试官的要求。
思路分析
思路一:使用栈
遍历的顺序时从头到尾,可输出的顺序确是从尾到头。*
也就是说:
第一个遍历的节点最后一个输出;而最后一个遍历的节点第一个输出
; 这就是典型的
先进后出
。 我们可以使用
栈
这种顺序; 每经过一个节点的时候,把该节点放入栈中。
当遍历完整个链表后,再从
栈顶开始逐个输出节点的值
,此时输出节点的顺序已经反转股哟开了*
/**
* @param listNode
* @return
* 使用栈 :数据结构
* 遍历的顺序时从头到尾,可输出的顺序确是从尾到头。
* 也就是说:第一个遍历的节点最后一个输出;而最后一个遍历的节点第一个输出;
* 这就是典型的先进后出。我们可以使用 栈 这种顺序
* 每经过一个节点的时候,把该节点放入栈中。当遍历完整个链表后,再从栈顶开始逐个输出节点的值,此时输出节点的顺序已经反转股哟开了
*
*/
public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> arrayList = new ArrayList<>();
Stack<ListNode> stack = new Stack<>();
//从前往后遍历整个链表
ListNode temp = listNode;
while(temp!=null){
stack.push(temp);//进栈
temp = temp.next; //遍历下一个节点
}
//遍历栈输出
int num = stack.size();
for(int i =0;i<num;i++){
System.out.println(i);
arrayList.add(stack.pop().val);
}
return arrayList;
}
思路二:使用递归
既然想到了用栈来实现这个函数,而
递归
的本质就是一个栈结构,于是很自然的又想到使用递归来实现;要实现反过来输出链表,我们每访问到一个节点的时候,先递归输出它后面的节点,在输出该节点自身
public static ArrayList<Integer> printListFromTailToHead2(ListNode listNode){
ArrayList<Integer> arrayList = new ArrayList<>();
ListNode temp = listNode;
if(temp!=null){//假如节点部位空
arrayList.addAll(printListFromTailToHead2(temp.next));//将arrayList添加
arrayList.add(temp.val);
}
return arrayList;
}
上面的代码有一个问题:
当链表非常长的时候,就会导致函数调用的层级很深,从而导致灌输
调用栈溢出
的问题; 显然基于栈循环实现的到吗的鲁棒性要好一些。
来源:CSDN
作者:alex-zhou96
链接:https://blog.csdn.net/ZHOUJIAN_TANK/article/details/104041561