解法一:栈
单链表只能从头到尾遍历,看到从尾到头就很自然的想到了栈,栈具有先进后出,后进先出的特性。在遍历单链表时,将节点依次压栈,遍历结束时,再依次弹栈,就实现了倒序输出。
C++具有STL库,可以很方便的用栈。
/**
* 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> ret;
stack<ListNode*> stack;
ListNode *temp = head;
while(temp)
{
stack.push(temp);
temp = temp->next;
}
while(!stack.empty())
{
ret.push_back(stack.top()->val);
stack.pop();
}
return ret;
}
};
时间复杂度
O
(
n
)
O(n)
O(n):单链表遍历,弹栈
空间复杂度
O
(
n
)
O(n)
O(n):需要创建一个等长的辅助栈
解法二:
如果用c呢?手写栈总归有点累。在这可以先遍历单链表获得长度,再开一个保存返回结果的等长的数组。然后再次遍历单链表,从数组尾开始保存值,也实现了倒序。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* reversePrint(struct ListNode* head, int* returnSize){
// 第一次遍历得到链表长
*returnSize = 0;
struct ListNode *temp = head;
while(temp)
{
(*returnSize)++;
temp = temp->next;
}
// 第二次遍历倒序保存节点的值
int *ret = malloc(sizeof(int)*(*returnSize));
temp = head;
for(int i=*returnSize-1; i>=0; i--)
{
ret[i] = temp->val;
temp = temp->next;
}
return ret;
}
时间复杂度
O
(
n
)
O(n)
O(n):遍历了两次链表
空间复杂度
O
(
1
)
O(1)
O(1):返回的数组不算在内。