1. 题目来源
链接:LeetCode 从尾到头打印链表
来源:LeetCode——《剑指-Offer》专项
2. 题目说明
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 1:
输入:head = [1,3,2]
输出:[2,3,1]
限制:
- 0 <= 链表长度 <= 10000
3. 题目解析
3.1 方法一:逆置链表、顺序遍历输出
在面试手撕编程题时,若需要修改原来的数据输入结构时,需要首先询问面试官是否允许修改。这取决于面试官的要求。切记!
在面试手撕编程题时,若需要修改原来的数据输入结构时,需要首先询问面试官是否允许修改。这取决于面试官的要求。切记!
在面试手撕编程题时,若需要修改原来的数据输入结构时,需要首先询问面试官是否允许修改。这取决于面试官的要求。切记!
在此只是简单复习一下单链表的原地逆置,即三指针原地逆置法。
参见代码如下:
// 执行用时 :8 ms, 在所有 C++ 提交中击败了67.78%的用户
// 内存消耗 :9.7 MB, 在所有 C++ 提交中击败了100.00%的用户
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int> vt;
if (head == nullptr)
return vt;
head = ReverseList(head);
for (ListNode* p = head; p != nullptr; p = p->next)
vt.push_back(p->val);
return vt;
}
ListNode* ReverseList(ListNode* pHead) {
if (pHead->next == nullptr || pHead==nullptr)
return pHead;
ListNode* pre = NULL;
ListNode* cur = pHead;
ListNode* next = NULL;
while (cur != NULL) {
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
};
3.2 方法二:辅助栈空间
“后进先出”,很自然能想到stack
的使用。
参见代码如下:
// 执行用时 :8 ms, 在所有 C++ 提交中击败了67.78%的用户
// 内存消耗 :9.9 MB, 在所有 C++ 提交中击败了100.00%的用户
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int> vt;
stack<int> st;
if (head == nullptr)
return vt;
for (ListNode* p = head; p != nullptr; p = p->next)
st.push(p->val);
while (!st.empty()) {
vt.push_back(st.top());
st.pop();
}
return vt;
}
};
3.3 方法三:递归法
简单的递归思想:递归本质上就是一个栈结构,每次访问到一个节点时,先递归输出它后面的节点,再输出该节点自身,递归即可反向输出。
递归方法虽然简单,但是当链表长度较长时,导致函数调用深度过深引发栈溢出。显然栈基于循环实现的代码的鲁棒性要好一点。
// 执行用时 :112 ms, 在所有 C++ 提交中击败了5.06%的用户
// 内存消耗 :265.9 MB, 在所有 C++ 提交中击败了100.00%的用户
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> vt;
vector<int> reversePrint(ListNode* head) {
if (head == nullptr)
return vt;
reversePrint(head->next);
vt.push_back(head->val);
return vt;
}
};