方法一

暴力法,时间复杂度较高

  1. public int[] reversePrint(ListNode head) {
  2. ListNode cur = head;
  3. List<Integer> list = new ArrayList<>();
  4. while (cur != null) {
  5. list.add(cur.val);
  6. cur = cur.next;
  7. }
  8. Collections.reverse(list);
  9. int[] res = new int[list.size()];
  10. for (int i = 0; i < list.size(); i++) {
  11. res[i] = list.get(i);
  12. }
  13. return res;
  14. }

方法二

递归法

解题思路:利用递归: 先走至链表末端,回溯时依次将节点值加入列表 ,这样就可以实现链表值的倒序输出。

Java 算法流程:
递推阶段: 每次传入 head.next ,以 head == null(即走过链表尾部节点)为递归终止条件,此时直接返回。
回溯阶段: 层层回溯时,将当前节点值加入列表,即tmp.add(head.val)。
最终,将列表 tmp 转化为数组 res ,并返回即可。

复杂度分析:
时间复杂度 O(N)O(N): 遍历链表,递归 NN 次。
空间复杂度 O(N)O(N): 系统递归需要使用 O(N)O(N) 的栈空间。

  1. // 递归法
  2. // 时间复杂度 O(N)O(N): 遍历链表,递归 NN 次。
  3. // 空间复杂度 O(N)O(N): 系统递归需要使用 O(N)O(N) 的栈空间。
  4. public int[] reversePrint(ListNode head) {
  5. recur(head);
  6. int[] res = new int[list.size()];
  7. for (int i = 0; i < res.length; i++) {
  8. res[i] = list.get(i);
  9. }
  10. return res;
  11. }
  12. List<Integer> list = new ArrayList<>();
  13. public void recur(ListNode node) {
  14. if (node == null) {
  15. return;
  16. }
  17. recur(node.next); // 先递归到最后节点
  18. list.add(node.val); // 回溯,加入此节点值
  19. }

方法三

辅助栈法:这种 先入后出 的需求可以借助 栈 来实现。

复杂度分析:
时间复杂度 O(N)O(N): 入栈和出栈共使用 O(N)O(N) 时间。
空间复杂度 O(N)O(N): 辅助栈 stack 和数组 res 共使用 O(N)O(N) 的额外空间。

  1. // 利用栈的特性
  2. // 时间复杂度 O(N)O(N): 入栈和出栈共使用 O(N)O(N) 时间。
  3. // 空间复杂度 O(N)O(N): 辅助栈 stack 和数组 res 共使用 O(N)O(N) 的额外空间。
  4. public int[] reversePrint(ListNode head) {
  5. Stack<Integer> stack = new Stack<Integer>();
  6. while (head != null) {
  7. stack.push(head.val);
  8. head = head.next;
  9. }
  10. int[] res = new int[stack.size()];
  11. for (int i = 0; i < res.length; i++) {
  12. res[i] = stack.pop();
  13. }
  14. return res;
  15. }