题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。
(输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。)
假如要从尾到头把链表输出,可以把指针反转,然后顺序输出,但是这样已经改变了链表的结构,不可取。而且,打印是一个只读的操作,我们不希望打印时修改内容,因此不能修改链表的结构。这时利用栈的特性,问题迎刃而解。
以下是牛客网上的解答
每经过一个结点的时候,把该结点放到一个栈中。当遍历完整个链表后,再从栈顶开始逐个输出结点的值,此时输出的结点的顺序已经反转过来了。
struct ListNode
{
public:
int val;
struct ListNode *next;
};
class Solution
{
public:
vector<int> printListFromTailToHead(struct ListNode * head)
{
ListNode * node = head;
stack<int> st;
int count = 0;
while (node != NULL)
{
cout << node ->val << endl;
st.push(node -> val);
count++;
node = node -> next;
}
//静态开辟vector,不能使用push_back
vector<int> res(count);
for(int i = 0; i < count && st.empty() != true; i++)
{
res[i] = st.top();
st.pop();
}
return res;
}
};
递归方法来完成
递归在本质上就是一个栈结构,要实现反过来输出链表,每访问到一个结点的时候,先递归输出它后面的结点,再输出该结点自身,这样链表的输出结构就反过来了。
<1>利用辅助函数来实现链表逆转
class Solution
{
public:
vector<int> printListFromTailToHead(struct ListNode * head)
{
vector<int> res;
printListFromTailToHeadRecursion(head, res);
return res;
}
void printListFromTailToHeadRecursion(struct ListNode * head, vector<int> &res)
{
if(head != NULL)
{
printListFromTailToHeadRecursion(head -> next, res);
res.push_back(head->val);
}
}
};
<2>用成员变量来存储vector
class Solution
{
public:
vector<int> res;
vector<int> printListFromTailToHead(struct ListNode * head)
{
if(head != NULL)
{
printListFromTailToHead(head -> next);
res.push_back(head->val);
}
return res;
}
};