• leetcode 剑指offer 06. 从尾到头打印链表


    06. 从尾到头打印链表

    输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

    示例 1:

    输入:head = [1,3,2]
    输出:[2,3,1]

    限制:

    0 <= 链表长度 <= 10000

    解法一:

    借用递归,递归时记录节点个数和当前结点的位置,递归到尾节点后创建数组,获取链表长度,回溯时开始给数组赋值

     1 class Solution {
     2     public int[] res;
     3     public int len = 0;
     4 
     5     // 借用列表
     6     public int[] reversePrint(ListNode head) {
     7         // 一边递归,一边记录节点个数
     8         recursion(head, 0);
     9         return res;
    10     }
    11 
    12     public void  recursion(ListNode head, int index){
    13         // 如果head不为空,节点个数加一
    14         if(head != null){
    15             // 后移
    16             //head = head.next;
    17             recursion(head.next, index + 1);
    18             // 等回溯回来的时候添加这个结点的值到int数组
    19             res[len - index - 1] = head.val;
    20         }else{        // 如果head为空,创建一个index长度的int数组
    21             res = new int[index];
    22             len = index;
    23         }
    24     }
    25 }

    leetcode运行时间为1ms, 空间为40.4mb

    复杂度分析:

    时间复杂度:对列表的进行了一次递归遍历,所以时间复杂度为O(n)

    空间复杂度:空间复杂度为栈的深度,即链表结点个数,另外还需要一个int[]数组用来存储结果,所以空间复杂度为O(2n)

    另一种写法:

    先用一个 list 把结果存下来,然后拷贝到数组中

     1 class Solution {
     2 
     3     public ArrayList<Integer> list = new ArrayList<>();
     4     // 借用递归
     5     public int[] reversePrint(ListNode head) {
     6 
     7         // 递归遍历链表,每次把结点插入到list
     8         recursion(head);
     9 
    10         int len = list.size();
    11         int[] res = new int[len];
    12         for(int i = 0; i < len; i++){
    13             res[i] = list.get(i);
    14         }
    15         return res;
    16     }
    17 
    18     public void recursion(ListNode head){
    19         if(head == null){
    20             return;
    21         }else{
    22             recursion(head.next);
    23             list.add(head.val);
    24         }
    25     }
    26 }

    leecode运行时间为1ms, 空间为40.2mb

    复杂度分析:

    时间复杂度:对列表的进行了一次递归遍历,后面还需要遍历一次 list 进行数据拷贝,所以时间复杂度为O(2n),

    空间复杂度:空间复杂度为栈的深度,即链表结点个数,另外还需要一个int[]数组用来存储结果,还用到了一个临时 list ,所以空间复杂度为O(3n)

    解法二:

    借助容器,ArrayList, stack, 比如 rraylist,遍历链表的时候每次把结果插入到 list,最后把 ArrayList 中的数据拷贝到一个数组即可

    遍历链表的时候不要把值插入到 list 头部,这样会导致 list 内部元素的移动,会大大降低效率。

     1 class Solution {
     2 
     3     // 借用递归
     4     public int[] reversePrint(ListNode head) {
     5         ArrayList<Integer> list = new ArrayList<>();
     6         // 遍历链表,每次把结点插入到list
     7         while(head != null){
     8             list.add(head.val);
     9             head = head.next;
    10         }
    11 
    12         int len = list.size();
    13         int[] res = new int[len];
    14         for(int i = 0; i < len; i++){
    15             res[i] = list.get(len - i - 1);
    16         }
    17         return res;
    18     }
    19 }

    leetcode运行时间为1ms,空间为39.2MB

    复杂度分析:

    时间复杂度:遍历了一次链表,遍历了一次list, 所以时间复杂度是O(2n)

    空间复杂度:一个len大小的list, 一个len大小的数组,所以空间复杂度为O(2n)

  • 相关阅读:
    web工作流管理系统开发之十八 工作流会签的相关实现
    工作流系统之三十一 回退流的实现
    web工作流管理系统开发之五 开源osworkflow之用户系统改造
    web工作流管理系统开发之十九 工作流系统的事务处理
    web工作流管理系统开发之十五 流程变量与表达式
    工作流系统开发之二十二 dotnet版工作流引擎
    web工作流管理系统开发之十七 任务管理
    利用httpclient+jericho多线程实现抓取网页内容
    工作流系统之二十六 .net工作流系统之扩展性
    工作流系统之二十九 详解工作流实例的一次流转
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/13743892.html
Copyright © 2020-2023  润新知