题目描述
输入一个链表,按链表从尾到头的顺序返回一个ArrayList。
解题思路
方法一:直接法
1、思路:看到从尾到头,想到利用栈先进后出的特性,于是乎开辟另一个栈空间来存储链表值,然后依次出栈赋值给数组。其实可以直接用vector存储链表值,最后通过std::reverse(vector.begin(), vector.end())来反转容器内容,这里需要注意的是vector.end()得到的是容器的最后一个单元+1的指针,reverse函数反转的范围是[vector.begin(), vector.end())。
2、代码:
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> ret;
stack<int> tmp;
if (!head) return ret;
while (head) {
tmp.push(head->val);
head = head->next;
}
while (!tmp.empty()) {
ret.push_back(tmp.top());
tmp.pop();
}
return ret;
}
};
3、复杂度:
时间复杂度:O(n);
空间复杂度:O(n)。
方法二:递归
1、思路:从链表头递归调用函数一直到链表尾部,遇到空指针时返回,就可以实现逆序输出。
2、代码:
class Solution {
public:
vector<int> ret;
void printList(vector<int> &ret, ListNode* cur) {
if (cur == nullptr) return;
printList(ret, cur->next);
ret.push_back(cur->val);
}
vector<int> printListFromTailToHead(ListNode* head) {
if (head == nullptr) return ret;
printList(ret, head);
return ret;
}
};
3、复杂度:
时间复杂度:O(n);
空间复杂度:O(n),递归栈的空间。
方法三:反转链表
1、思路:用头插法把链表进行反转,然后遍历。
2、代码:
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
ListNode *newHead = NULL;
ListNode *node;
vector<int> ret;
if (!head) return ret;
while (head) {
//1. 对之前的链表做头删
node = head;
head = head->next;
//2. 对新链表做头插
node->next = newHead;
newHead = node;
}
while (newHead) {
ret.push_back(newHead->val);
newHead = newHead->next;
}
return ret;
}
};
3、复杂度:
时间复杂度:O(n);
空间复杂度:O(1)。