• 剑指Offer_#6_从尾到头打印链表


    剑指Offer_#6_从尾到头打印链表

    Contents

    题目

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

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

    限制:
    0 <= 链表长度 <= 10000

    思路分析

    方法1:辅助栈

    遍历链表只能从头到尾,而这里需要我们从尾到头打印链表的节点,这可以借助栈的"先进后出"特点来实现。按照正序将各个节点的值入栈,出栈的时候就是倒序的。

    方法2:递归

    算法流程

    先遍历到链表尾部,然后在回溯的过程中把值添加到结果数组中。

    1. 终止条件:head == null,即遍历到链表的尾部
    2. 递推过程:recur(head.next)
    3. 回溯过程:list.add(head)

    在递归过程中,暂存结果的变量list可以写成一个类全局变量,也可以写成一个递归函数的参数,详见代码。

    解答

    解答1:辅助栈

    class Solution {
        public int[] reversePrint(ListNode head) {
            Stack<Integer> stack = new Stack<>();
            while(head != null){
                stack.add(head.val);
                head = head.next;
            }
            int[] res = new int[stack.size()];
            for(int i = 0;i <= res.length - 1;i++){
                res[i] = stack.pop();
            }
            return res;
        }
    }

    复杂度分析

    时间复杂度:O(n)
    空间复杂度:O(n)

    解答2:递归

    list做全局变量

    class Solution {
        List<Integer> list = new ArrayList<>();
        public int[] reversePrint(ListNode head) {
            //调用递归函数
            recur(head);
            //将结果转换为int数组
            int[] res = new int[list.size()];
            for(int i = 0;i <= res.length - 1;i++){
                res[i] = list.get(i);
            }
            return res;
        }
    
        private void recur(ListNode head){
            //终止条件:已经遍历到链表最尾端
            if(head == null) return;
            //递归调用开始,程序在此被阻塞住,直到满足终止条件,开始回溯
            recur(head.next);
            //回溯
            list.add(head.val);
        }
    }

    list做递归方法参数

    class Solution {
        public int[] reversePrint(ListNode head) {
            List<Integer> list = new ArrayList<>();
            //调用递归函数
            recur(head, list);
            //将结果转换为int数组
            int[] res = new int[list.size()];
            for(int i = 0;i <= res.length - 1;i++){
                res[i] = list.get(i);
            }
            return res;
        }
    
        private void recur(ListNode head,List<Integer> aList){
            //终止条件:已经遍历到链表最尾端
            if(head == null) return;
            //递归调用开始,程序在此被阻塞住,直到满足终止条件,开始回溯
            recur(head.next,aList);
            //回溯
            aList.add(head.val);
        }
    }

    复杂度分析

    时间复杂度:O(n),递归函数调用n次
    空间复杂度:O(n),递归调用n次,占用O(n)的栈空间

  • 相关阅读:
    PHP读写XML文件的四种方法
    如何在linux系统中设置静态ip地址
    Memcached和Memcache安装(64位win7)
    Mysql存储过程和函数区别介绍
    随笔
    Vue 中使用axios传参数,后端收不到数据
    vs2019创建mvc连接mysql
    dapper多表查询
    Java并发编程:volatile关键字解析
    Mysql Innodb 间隙锁浅析
  • 原文地址:https://www.cnblogs.com/Howfars/p/13410626.html
Copyright © 2020-2023  润新知