一、题目描述
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例
输入:head = [1,3,2]
输出:[2,3,1]
限制
0<=链表长度<=10000
二、思路分析
注:思路分析中的一些内容和图片参考自力扣各位前辈的题解,感谢他们的无私奉献
思路----使用递归的方法
采用方法
可以使用递归: 先走至链表末端,回溯时依次将各个结点的值从前往后放入数组中 ,这样就可以实现链表值的倒序输出
方法流程
每次进入函数时,判断链表是否为空。
----如果为空,说明已经在链表末尾后面了。此时,创建一个数组用来保存各个结点的值,同时将数组元素个数设置为0
----如果不为空,说明还没到链表末尾,继续递归调用这个函数,此时传入的结点是当前结点的下一个结点。在递归调用这个函数的这行代码后面,将当前结点的值放在数组中,同时让数组元素个数+1
复杂度分析
时间复杂度O(N)
:遍历链表,递归N
次。
空间复杂度O(N)
:系统递归需要使用O(N)
的栈空间。
思路----使用栈的方法
采用方法
可以使用栈:先遍历链表,并把每个结点的值压入栈中,然后从栈顶开始依次取出栈中元素作为数组输出
方法流程
①创建一个栈,并初始化栈顶元素下标。
②使用一个循环将链表各个结点的值放入栈,每次放入时同步更新栈顶元素下标
③创建一个数组,使用一个循环从栈顶元素下标开始将栈中的值依次放入数组中
④返回这个数组
复杂度分析
时间复杂度O(N)
:入栈和出栈共使用O(N)
时间。
空间复杂度O(N)
:辅助栈 stack 和数组 res 共使用O(N)
的额外空间。
三、整体代码
使用递归方法的整体代码如下
/**
* 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){
//当前结点为空,说明走到链表末尾了
if(head == NULL){
//此时要往回递归了,先初始化一些东西。
//首先,元素个数为0,所以*returnSize=0
//其次,要创建数组了
//最后,将数组返回
*returnSize = 0;
int *arr = (int*)malloc(sizeof(int)*10000);
return arr;
}
//当前结点不为空,说明还没到链表末尾,需要继续继续递归处理下一个结点
int *ans = reversePrint(head->next, returnSize);
//此时开始往回递归,每次将结点的值放在ans[*returnsize],同时让(*returnSize)+1
ans[(*returnSize)++] = head->val;
return ans;
}
运行,验证通过
使用栈的方法的整体代码如下:
/**
* 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){
int stack[10000]; //创建栈
int top = -1; //初始化栈顶元素下标
//将链表各个结点元素依次入栈
while(head != NULL){
stack[++top] = head->val;
head = head->next;
}
//开辟一个数组
*returnSize = top+1;
int* res = (int*)malloc(sizeof(int) * (*returnSize));
//栈中元素依次出栈,并依次放入数组中
for(int i=0; top >= 0; top--, i++)
res[i] = stack[top];
return res;
}
运行,验证通过