zoukankan      html  css  js  c++  java
  • 剑指Offer对答如流系列

    面试题5:从尾到头打印链表

    题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。链表结点定义如下:

    public class ListNode {
            int val;
            ListNode next = null;
    
            ListNode(int val) {
                this.val = val;
            }
        }
    

    方法一:递归

    这里选择了递归的方式,当递归到最底层的时候,呈现给我们的数值是链表的最后一位。这个时候我们用ArrayList<Integer>接收。

    最终ArrayList<Integer>中存储的值的顺序就是链表从尾到头的数值的顺序。我们直接遍历ArrayList<Integer>即可。

    但是这种方法有缺陷,当链表长度过长的时候,会使得递归的深度会很大,有可能导致栈的溢出。

    public class Solution {
    
        ArrayList<Integer> arrayList = new ArrayList<>();
      
        public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
            if (listNode != null) {
                printListFromTailToHead(listNode.next);
                arrayList.add(listNode.val);
            }
            return arrayList;
        }
    
        public class ListNode {
            int val;
            ListNode next = null;
    
            ListNode(int val) {
                this.val = val;
            }
        }
    }
    

    方法二:利用栈

    利用栈先进后出的特点: 创建一个栈顺序接收链表的数值,然后遍历栈实现数值排列逆序的输出。相对于递归,我认为这是一种更合适的方法。

    public class Solution {
    
        public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
            if (listNode == null) {
                ArrayList<Integer> arrayList = new ArrayList<>();
                return arrayList;
            }
            //定义一个栈
            Deque<Integer> stack = new ArrayDeque<>();
            while (listNode != null) {
                stack.push(listNode.val);//入栈
                listNode = listNode.next;
            }
            while (!stack.isEmpty()) {
                arrayList.add(stack.pop());//出栈,并添加到arrayList
            }
            return arrayList;
        }
    
     
        public class ListNode {
            int val;
            ListNode next = null;
    
            ListNode(int val) {
                this.val = val;
            }
        }
    }
    

    链表是一种动态数据结构,是因为在创建链表时,无须知道链表的长度。当插入一个结点时,我们只需要为新结点分配内存,然后调整指针的指向来确保新结点被链接到链表当中。内存分配不是在创建链表时一次性完成,而是每添加一个结点分配一次内存。由于没有闲置的内存,链表的空间效率比数组高。

    由于链表非常灵活而且代码相对简练的特点,在面试中考察的是非常多的。

  • 相关阅读:
    OEP
    壳的执行过程
    JavaScript RSA算法简单实现(转)
    创建根证书及其子证书
    从零开始学习Sencha Touch MVC应用之十四
    javascript base64
    discuz 文档地址
    虚拟机共享数据
    转Javascript到PHP RSA加密通讯的简单实现
    PHP RSA研究
  • 原文地址:https://www.cnblogs.com/JefferyChenXiao/p/12246252.html
Copyright © 2011-2022 走看看