原题要求
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 1:
输入:head = [1,3,2]
输出:[2,3,1]
限制:
0 <= 链表长度 <= 10000
解题过程
递归 | 时间复杂度: O ( n ) O(n) O(n) | 空间复杂度 O ( n ) O(n) O(n) | 推荐
虽然时间性能不及下方的迭代,但是理解递归的调用过程有助于后续的学习!
ps:递归从下图就可以看出,其实就好像在所有的元素里走了一圈。如果执行操作在递归之前,则在每个正向调用的过程中都执行一遍。但是!如果执行操作在递归之后,就会在最终的递归出口处开始,继续执行没有执行完的操作!有那味道没!哈哈哈
详情可以参考:三张图简单理解回溯算法
class Solution {
List<Integer> list = new ArrayList<>();
public int[] reversePrint(ListNode head) {
recur(head);
int[] res = new int[list.size()];
// 正向遍历即可,在list中,元素已经反转
for(int i = 0; i < res.length; i++) res[i] = list.get(i);
return res;
}
// 递归的方式
public void recur(ListNode head){
if(head == null) return;
recur(head.next);
// add操作要在递归函数之后
// 第一次add操作,就是最后一次递归结束的时候
list.add(head.val);
}
}
迭代 | 时间复杂度: O ( n ) O(n) O(n) | 空间复杂度 O ( n ) O(n) O(n) | 推荐
class Solution {
public int[] reversePrint(ListNode head) {
int count = countNodes(head);
int[] res = new int[count];
ListNode cur = head;
// 逆序给数组赋值即可
for(int i = count - 1; i >= 0; i--){
res[i] = cur.val;
cur = cur.next;
}
return res;
}
// 首先计数,得到节点数量
public int countNodes(ListNode head){
int count = 0;
ListNode cur = head;
while(cur != null){
count++;
cur = cur.next;
}
return count;
}
}