剑指 offer 06. 从尾到头打印链表
问题: 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
辅助栈法
题目中最明显的字眼就是是从尾到头,所以我一开始就想到用栈来存储链表中的值。
首先遍历链表中的每一个节点。最开始head是链表的头指针,每一次遍历将head更新为head->next,并将head->value也就是这个节点的值存到预设的栈中;整个遍历过程的终止条件为head == NULL。遍历完后栈中,因为栈的特点是先入后出,所以从栈顶到栈尾存到值的顺序就是链表中节点的逆序。
最后逐个将栈中的值从栈顶逐个弹出来,先用temp.top()取出栈顶的值,再用temp.pop()弹出栈顶的值。这里pop()函数没有返回值,只是单纯的删除栈顶的值,并将指针指向下面一个将其设为栈顶。
#include<vector>
#include<stack>
#include<iostream>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
stack<int> temp;
while (head != NULL)
{
temp.push(head->val);
head = head->next;
}
vector<int> res;
while (!temp.empty())
{
res.push_back(temp.top());
temp.pop();
}
return res;
}
};
int main(){
ListNode a(1);
ListNode b(2);
ListNode c(3);
a.next = &b;
b.next = &c;
Solution d;
vector<int> res = d.reversePrint(&a);
for(int n:res){
cout << n << endl;
}
return 0;
}
递归法:
我用栈整完后看了官方的解答,它给了两个答案,第二个就是我上面用的辅助栈法。第一个它用的是递归法,也就是它访问每一个链表的节点后它不做处理,继续向后递归,直到最后一个节点的是时候才开始将节点的值添加到链表中,然后递归结束,返回到上一层将倒数第二个节点添加到链表中。正常人的思路肯定第一个想到的是用栈处理,递归真的很难上来就想到。
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
recur(head);
return res;
}
private:
vector<int> res;
void recur(ListNode* head) {
if(head == nullptr) return;
recur(head->next);
res.push_back(head->val);
}
};
作者:Krahets
链接:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/5d8831/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
后面我可能还会二刷,要是想到新的解法或者发现了其他更好有特点的解法我还会加在这里。