一、需求
- 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
二、数组法
2.1 思路分析
- 求链表的长度,根据长度申请数组空间;
- 将链表的第一个值存储到数组最后位置,第二个值存储到数组倒数第二个位置,以此类推。
2.2 代码实现
public int[] reversePrint(ListNode head) {
int len = 0;
ListNode p = head;
while(p != null) {
len++;
p = p.next;
}
int[] arr = new int[len];
p = head;
for(int i = len-1; i >= 0; i--) {
arr[i] = p.val;
p = p.next;
}
return arr;
}
2.3 复杂度分析
- 时间复杂度为O(n);
- 空间复杂度为O(n);
三、栈存储
3.1 思路分析
- 我们遍历链表,把每个节点都存储到栈中;
- 根据栈的大小,新建一个数组;
- 对栈执行出栈操作,将出栈的元素值存放到数组中;
3.2 代码实现
class Solution {
public int[] reversePrint(ListNode head) {
Stack<ListNode> stack = new Stack<>();
ListNode p = head;
while(p != null) {
stack.push(p);
p = p.next;
}
int[] arr = new int[stack.size()];
for(int i = 0; i < arr.length; i++) {
arr[i] = stack.pop().val;
}
return arr;
}
}
3.3 复杂度分析
- 时间复杂度为O(n);
- 空间复杂度为O(n);
四、递归法
4.1 思路分析
- 类似于二叉树的后序遍历,我们先递归至最后一个节点,令递归规律为recur(head.next),递归的终止条件就是若head == null,那就直接返回空,返回后我们将当前head对应的值加入到List集合中;
4.2 代码实现
class Solution {
List<Integer> list = new ArrayList<>();
public int[] reversePrint(ListNode head) {
recur(head);
int[] arr = new int[list.size()];
for(int i = 0; i < arr.length; i++) {
arr[i] = list.get(i);
}
return arr;
}
//该方法将链表的值从尾到头存储到集合中
public void recur(ListNode head) {
if(head == null) return;
recur(head.next);
list.add(head.val);
}
}
4.3 复杂度分析
- 时间复杂度为O(n),其中遍历链表消耗O(n),递归消耗O(n);
- 空间复杂度为O(n),其中定义数组消耗O(n),递归消耗O(n);