学习了很久的链表结构,但是在一些链表面试题中却没办法很好的使用其他的相关数据结构来解决链表的问题,就比如在书中的链表逆序打印问题(这里指的是单向链表);
输入一个链表,从尾到头打印链表每个节点的值。
开始我的思路就是给链表额外添加一个指针,将指针指向链表中的每个节点的时候,改变节点的next指向,但是会有一旦改变某个节点的指向就会使得下一个节点找不到,从而不能实现逆序打印,如果在改变指向前保存下一个节点,虽然可以,但是指针变量的开销大,况且如果面试官说不可以改变链表本身呢?
这就是需要考虑在不改变链表结构的前提下,如何可以在顺序的第一次遍历直到最后一个的尾节点,从而输出的是逆序的呢?
联系以前所学的知识,我们可以想到,后进先出的栈,这道题完全可以使用压栈的方式,从头节点开始,将节点压入栈,直到最后一个节点压栈完成,再将栈顶元素一个个pop掉,从而就实现了将链表逆序打印。栈实现逆序,而栈在逆序的过程中就是一个个的子问题循环实现,由此,我们可以想到,递归就是在解决一个个的子问题,那么,逆序打印链表也就可以用递归实现。
除此之外,递归也可以实现逆序打印,但是如果在数据量较大的时候,递归反而是冗杂,所以要考虑在不同场景下的代码使用。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
stack<ListNode*> nodes;
vector<int> res;
ListNode* pNode=head;
while(pNode != NULL){
nodes.push(pNode);
pNode=pNode->next;
}
while(!nodes.empty()){
res.push_back(nodes.top()->val);
nodes.pop();
}
return res;
}
};